• 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 #include <sys/stat.h>
20 
21 #include <ability_context.h>
22 #include <ability_manager_client.h>
23 #include <application_context.h>
24 #include <bundlemgr/launcher_service.h>
25 #include <common/rs_common_def.h>
26 #include <hisysevent.h>
27 #include <parameters.h>
28 #include <hitrace_meter.h>
29 #include "hitrace/hitracechain.h"
30 #include "parameter.h"
31 #include "resource_manager.h"
32 #include "session/host/include/pc_fold_screen_manager.h"
33 #include "publish/scb_dump_subscriber.h"
34 #include <ui/rs_node.h>
35 
36 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
37 #include <display_power_mgr_client.h>
38 #endif
39 
40 #ifdef POWER_MANAGER_ENABLE
41 #include <power_mgr_client.h>
42 #endif
43 
44 #ifdef RES_SCHED_ENABLE
45 #include "res_type.h"
46 #include "res_sched_client.h"
47 #endif
48 
49 #include "anomaly_detection.h"
50 #include "color_parser.h"
51 #include "common/include/fold_screen_state_internel.h"
52 #include "common/include/session_permission.h"
53 #include "display_manager.h"
54 #include "distributed_client.h"
55 #include "dms_reporter.h"
56 #include "hidump_controller.h"
57 #include "image_source.h"
58 #include "perform_reporter.h"
59 #include "rdb/starting_window_rdb_manager.h"
60 #include "res_sched_client.h"
61 #include "rs_adapter.h"
62 #include "scene_input_manager.h"
63 #include "scene_screen_change_listener.h"
64 #include "scene_system_ability_listener.h"
65 #include "screen_session_manager_client/include/screen_session_manager_client.h"
66 #include "session/host/include/ability_info_manager.h"
67 #include "session/host/include/main_session.h"
68 #include "session/host/include/multi_instance_manager.h"
69 #include "session/host/include/scb_system_session.h"
70 #include "session/host/include/scene_persistent_storage.h"
71 #include "session/host/include/session_change_recorder.h"
72 #include "session/host/include/session_utils.h"
73 #include "session/host/include/sub_session.h"
74 #include "session_helper.h"
75 #include "session_manager_agent_controller.h"
76 #include "singleton_container.h"
77 #include "softbus_bus_center.h"
78 #include "user_switch_reporter.h"
79 #include "window_helper.h"
80 #include "xcollie/watchdog.h"
81 #include "xcollie/xcollie.h"
82 #include "xcollie/xcollie_define.h"
83 #include "session_permission.h"
84 
85 #include "ui_effect_manager.h"
86 #ifdef MEMMGR_WINDOW_ENABLE
87 #include "mem_mgr_client.h"
88 #include "mem_mgr_window_info.h"
89 #endif
90 
91 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
92 #include "sec_comp_enhance_kit.h"
93 #endif
94 
95 #ifdef IMF_ENABLE
96 #include <input_method_controller.h>
97 #endif // IMF_ENABLE
98 
99 namespace OHOS::Rosen {
100 namespace {
101 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
102 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
103 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
104 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
105 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
106 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
107 constexpr uint32_t MAX_BRIGHTNESS = 255;
108 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
109 constexpr int32_t SCALE_DIMENSION = 2;
110 constexpr int32_t TRANSLATE_DIMENSION = 2;
111 constexpr int32_t ROTAION_DIMENSION = 4;
112 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
113 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
114 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
115 const std::string EMPTY_DEVICE_ID = "";
116 const std::string STARTWINDOW_TYPE = "startWindowType";
117 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
118 
119 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
120 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
121 constexpr int VALUE_MAX_WIDTH = 5;
122 constexpr int MAX_RESEND_TIMES = 6;
123 constexpr int ORIEN_MAX_WIDTH = 12;
124 constexpr int OFFSET_MAX_WIDTH = 8;
125 constexpr int SCALE_MAX_WIDTH = 8;
126 constexpr int PID_MAX_WIDTH = 8;
127 constexpr int PARENT_ID_MAX_WIDTH = 6;
128 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
129 constexpr int32_t CANCEL_POINTER_ID = 99999999;
130 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
131 const std::string ARG_DUMP_ALL = "-a";
132 const std::string ARG_DUMP_WINDOW = "-w";
133 const std::string ARG_DUMP_SCREEN = "-s";
134 const std::string ARG_DUMP_DISPLAY = "-d";
135 const std::string ARG_DUMP_PIPLINE = "-p";
136 const std::string ARG_DUMP_SCB = "-b";
137 const std::string ARG_DUMP_DETAIL = "-c";
138 const std::string ARG_DUMP_RECORD = "-v";
139 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
140 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
141 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
142 constexpr char SMALL_FOLD_PRODUCT_TYPE = '2';
143 constexpr uint32_t MAX_SUB_WINDOW_LEVEL = 10;
144 constexpr uint64_t VIRTUAL_DISPLAY_ID = 999;
145 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
146 constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000;
147 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 50;
148 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8;
149 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3;
150 constexpr uint64_t NOTIFY_START_ABILITY_TIMEOUT = 4000;
151 constexpr uint64_t START_UI_ABILITY_TIMEOUT = 5000;
152 constexpr int32_t FORCE_SPLIT_MODE = 5;
153 constexpr int32_t NAV_FORCE_SPLIT_MODE = 6;
154 const std::string FB_PANEL_NAME = "Fb_panel";
155 
156 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
157     {"unspecified",                         OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
158     {"landscape",                           OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
159     {"portrait",                            OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
160     {"follow_recent",                       OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
161     {"landscape_inverted",                  OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
162     {"portrait_inverted",                   OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
163     {"auto_rotation",                       OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
164     {"auto_rotation_landscape",             OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
165     {"auto_rotation_portrait",              OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
166     {"auto_rotation_restricted",            OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
167     {"auto_rotation_landscape_restricted",  OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
168     {"auto_rotation_portrait_restricted",   OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
169     {"locked",                              OHOS::AppExecFwk::DisplayOrientation::LOCKED},
170     {"auto_rotation_unspecified",           OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
171     {"follow_desktop",                      OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
172 };
173 
174 const std::map<std::string, StartWindowType> CONVERT_STRING_TO_START_WINDOW_TYPE_MAP = {
175     {"REQUIRED_SHOW", StartWindowType::DEFAULT},
176     {"REQUIRED_HIDE", StartWindowType::RETAIN_AND_INVISIBLE},
177     {"OPTIONAL_SHOW", StartWindowType::DEFAULT},
178 };
179 
180 const std::unordered_set<std::string> LAYOUT_INFO_WHITELIST = {
181     "SCBSmartDock",
182     "SCBExtScreenDock",
183     "status_bar_tray",
184     "status_bar_personal",
185     "status_bar_sound_panel",
186     "status_bar_notification_panel",
187     "status_bar_input_panel",
188     "status_bar_control_center",
189     "status_bar_wifi_panel",
190     "status_bar_input_method",
191     "status_bar_assistant_translate",
192     "status_bar_quick_note",
193     "status_bar_bluetooth_panel",
194     "status_bar_battery_panel",
195     "status_bar_focus_mode_paddle",
196     "SCBStatusBar"
197 };
198 
199 const std::chrono::milliseconds WAIT_TIME(3 * 1000); // 3 * 1000 wait for 3s
200 
GetCurrentTime()201 std::string GetCurrentTime()
202 {
203     struct timespec tn;
204     clock_gettime(CLOCK_REALTIME, &tn);
205     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
206         static_cast<uint64_t>(tn.tv_nsec);
207     return std::to_string(uTime);
208 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)209 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
210 {
211     return a.first < b.first;
212 }
213 
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)214 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
215 {
216     if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
217         value = (*item.intsValue_)[0];
218         return true;
219     }
220     return false;
221 }
222 
GetPid()223 int32_t GetPid()
224 {
225     static int32_t pid = static_cast<int32_t>(getpid());
226     return pid;
227 }
228 
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)229 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
230 {
231     auto& metadata = abilityInfo->metadata;
232     for (const auto& item : metadata) {
233         if (item.name == "enable.remove.starting.window") {
234             TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window=%{public}s", item.value.c_str());
235             return item.value == "true";
236         }
237     }
238     TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "enable.remove.starting.window default false");
239     return false;
240 }
241 
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)242 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
243     AppExecFwk::ExtensionAbilityType extensionAbilityType)
244 {
245     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
246           element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
247     static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
248         AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
249     };
250     static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
251         std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
252         std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
253         std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
254         std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
255         std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
256         std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
257         std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
258         std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
259         std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
260         std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
261         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
262         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
263         std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
264         std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
265         std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
266         std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
267         std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
268         std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
269         std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
270         std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
271         std::make_tuple("com.huawei.hmos.settings", "WifiWindowSettingsAbility", "pc_settings"),
272         std::make_tuple("com.ohos.mms", "DeskDialogExtensionAbility", "entry"),
273         std::make_tuple("com.ohos.sceneboard", "ThemeChargingAbility", "engineservice"),
274         std::make_tuple("com.ohos.commondialog", "FoldStatusAbility", "phone_commondialog"),
275         std::make_tuple("com.ohos.commondialog", "SecondaryReflexionAbility", "phone_commondialog"),
276     };
277 
278     if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
279         TLOGI(WmsLogTag::WMS_UIEXT, "ability in white list");
280         return true;
281     }
282 
283     auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
284         auto& [bundleName, abilityName, _] = item;
285         return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
286     });
287     if (it != elementNameWhitelist.end()) {
288         return true;
289     }
290 
291     TLOGD(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
292     return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
293         PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
294 }
295 
296 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
297 public:
298     BundleStatusCallback() = default;
299     virtual ~BundleStatusCallback() = default;
300 
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)301     void OnBundleStateChanged(const uint8_t installType,
302         const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
303 
OnBundleAdded(const std::string & bundleName,const int userId)304     void OnBundleAdded(const std::string& bundleName, const int userId) override
305     {
306         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
307     }
308 
OnBundleUpdated(const std::string & bundleName,const int userId)309     void OnBundleUpdated(const std::string& bundleName, const int userId) override
310     {
311         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
312     }
313 
OnBundleRemoved(const std::string & bundleName,const int userId)314     void OnBundleRemoved(const std::string& bundleName, const int userId) override
315     {
316         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
317     }
318 };
319 
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)320 bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
321 {
322     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
323         !avoidArea.rightRect_.IsUninitializedRect()) {
324         return false;
325     }
326     if (avoidArea.bottomRect_.IsUninitializedRect()) {
327         return true;
328     }
329     auto diff =
330         std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
331     return isVisible && diff <= 1;
332 }
333 
334 enum class UpdateStartingWindowColorCacheResult : uint32_t {
335     SUCCESS = 0,
336     COLOR_MAP_BUNDLE_NOT_FOUND,
337     COLOR_MAP_KEY_PAIR_NOT_FOUND,
338     INFO_MAP_BUNDLE_NOT_FOUND,
339     INFO_MAP_KEY_PAIR_NOT_FOUND,
340 };
341 } // namespace
342 
CreateInstance()343 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
344 {
345     sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
346     sessionManager->Init();
347     return sessionManager;
348 }
349 
GetInstance()350 SceneSessionManager& SceneSessionManager::GetInstance()
351 {
352     static sptr<SceneSessionManager> instance = CreateInstance();
353     return *instance;
354 }
355 
SceneSessionManager()356 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
357 {
358     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
359     if (!mainHandler_) {
360         auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
361         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
362     }
363     currentUserId_ = DEFAULT_USERID;
364     launcherService_ = sptr<AppExecFwk::LauncherService>::MakeSptr();
365     if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
366         TLOGE(WmsLogTag::DEFAULT, "Failed to register bundle status callback.");
367     }
368 
369     collaboratorDeathRecipient_ = sptr<AgentDeathRecipient>::MakeSptr(
370         [this](const sptr<IRemoteObject>& remoteObject) { this->ClearAllCollaboratorSessions(); });
371 
372     scbDumpSubscriber_ = ScbDumpSubscriber::Subscribe();
373 
374     listenerController_ = std::make_shared<SessionListenerController>(taskScheduler_);
375     windowFocusController_ = sptr<WindowFocusController>::MakeSptr();
376     ffrtQueueHelper_ = std::make_shared<FfrtQueueHelper>();
377 }
378 
~SceneSessionManager()379 SceneSessionManager::~SceneSessionManager()
380 {
381     ScbDumpSubscriber::UnSubscribe(scbDumpSubscriber_);
382     SessionChangeRecorder::GetInstance().stopLogFlag_.store(true);
383 }
384 
Init()385 void SceneSessionManager::Init()
386 {
387     bool isScbCoreEnabled = system::GetParameter("persist.window.scbcore.enable", "1") == "1";
388     Session::SetScbCoreEnabled(isScbCoreEnabled);
389     bool isBackgroundWindowNotifyEnabled = system::GetParameter("persist.window.background.notify.enable", "0") == "1";
390     Session::SetBackgroundUpdateRectNotifyEnabled(isBackgroundWindowNotifyEnabled);
391 
392     constexpr uint64_t interval = 5 * 1000; // 5 second
393     if (HiviewDFX::Watchdog::GetInstance().AddThread(
394         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
395         TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
396     }
397 
398     bundleMgr_ = GetBundleManager();
399 
400     // Parse configuration.
401     LoadWindowSceneXml();
402     LoadWindowParameter();
403     InitPrepareTerminateConfig();
404 
405     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(sptr<DisplayChangeListener>::MakeSptr());
406     ScreenSessionManagerClient::GetInstance().RegisterScreenConnectionChangeListener(
407         sptr<ScreenConnectionChangeListener>::MakeSptr());
408 
409     // create handler for inner command at server
410     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
411     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
412     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
413     if (ret != 0) {
414         TLOGW(WmsLogTag::DEFAULT, "Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
415     }
416     taskScheduler_->SetExportHandler(eventHandler_);
417 
418     scbSessionHandler_ = sptr<ScbSessionHandler>::MakeSptr();
419     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
420     StartWindowInfoReportLoop();
421     TLOGI(WmsLogTag::DEFAULT, "SSM init success.");
422 
423     RegisterAppListener();
424     openDebugTrace_ = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
425     isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1")  == "1";
426 
427     // window recover
428     RegisterSessionRecoverStateChangeListener();
429     RegisterRecoverStateChangeListener();
430 
431     // Input init.
432     SceneInputManager::GetInstance().Init();
433     RegisterFlushWindowInfoCallback();
434 
435     // DFX
436     SessionChangeRecorder::GetInstance().Init();
437 
438     // MMI window state error check
439     int32_t retCode = MMI::InputManager::GetInstance()->
440         RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
441         this->NotifyWindowStateErrorFromMMI(pid, persistentId);
442     });
443     TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
444 
445     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
446         MultiInstanceManager::GetInstance().Init(bundleMgr_, taskScheduler_);
447         MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
448     }
449     AbilityInfoManager::GetInstance().Init(bundleMgr_);
450     AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
451 
452     InitVsyncStation();
453     UpdateDarkColorModeToRS();
454     CreateRootSceneSession();
455     foldChangeCallback_ = std::make_shared<FoldScreenStatusChangeCallback>(
456         std::bind(&SceneSessionManager::UpdateSessionWithFoldStateChange, this, std::placeholders::_1,
457         std::placeholders::_2, std::placeholders::_3));
458     PcFoldScreenManager::GetInstance().RegisterFoldScreenStatusChangeCallback(0, foldChangeCallback_);
459 
460     InitSnapshotCache();
461 }
462 
RegisterSessionRecoverStateChangeListener()463 void SceneSessionManager::RegisterSessionRecoverStateChangeListener()
464 {
465     sessionRecoverStateChangeFunc_ = [this](const SessionRecoverState& state,
466         const sptr<WindowSessionProperty>& property) THREAD_SAFETY_GUARD(SCENE_GUARD) {
467             this->OnSessionRecoverStateChange(state, property);
468         };
469 }
470 
OnSessionRecoverStateChange(const SessionRecoverState & state,const sptr<WindowSessionProperty> & property)471 void SceneSessionManager::OnSessionRecoverStateChange(const SessionRecoverState& state,
472         const sptr<WindowSessionProperty>& property)
473 {
474     TLOGI(WmsLogTag::WMS_RECOVER, "id: %{public}d, state:%{public}u", property->GetPersistentId(), state);
475     switch (state) {
476         case SessionRecoverState::SESSION_START_RECONNECT:
477             // The server session has not request yet.
478             UpdateRecoverPropertyForSuperFold(property);
479             RecoverSessionInfo(property);
480             break;
481         case SessionRecoverState::SESSION_FINISH_RECONNECT: {
482             // The server session has been request.
483             auto sessionInfo = property->GetSessionInfo();
484             auto persistentId = sessionInfo.persistentId_;
485             auto sceneSession = GetSceneSession(persistentId);
486             if (sceneSession == nullptr) {
487                 break;
488             }
489             if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
490                 sceneSession->SetRecovered(true);
491                 recoverSceneSessionFunc_(sceneSession, sessionInfo);
492                 sceneSession->SetWindowShadowEnabled(property->GetWindowShadowEnabled());
493             } else {
494                 sceneSession->NotifyFollowParentMultiScreenPolicy(sessionInfo.isFollowParentMultiScreenPolicy);
495                 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
496                 CacheSpecificSessionForRecovering(sceneSession, property);
497                 sceneSession->SetWindowAnchorInfo(property->GetWindowAnchorInfo());
498             }
499             NotifySessionUnfocusedToClient(persistentId);
500             break;
501         }
502         default:
503             break;
504     }
505 }
506 
RegisterRecoverStateChangeListener()507 void SceneSessionManager::RegisterRecoverStateChangeListener()
508 {
509     recoverStateChangeFunc_ = [this](const RecoverState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
510         OnRecoverStateChange(state);
511     };
512 }
513 
OnRecoverStateChange(const RecoverState & state)514 void SceneSessionManager::OnRecoverStateChange(const RecoverState& state)
515 {
516     TLOGI(WmsLogTag::WMS_RECOVER, "state: %{public}u", state);
517     switch(state) {
518         case RecoverState::RECOVER_INITIAL:
519             break;
520         case RecoverState::RECOVER_ENABLE_INPUT:
521             SetDisplayBrightness(INVALID_BRIGHTNESS);
522             break;
523         default:
524             break;
525     }
526 }
527 
RegisterFlushWindowInfoCallback()528 void SceneSessionManager::RegisterFlushWindowInfoCallback()
529 {
530     SceneInputManager::GetInstance().
531         RegisterFlushWindowInfoCallback([this]() { FlushWindowInfoToMMI(); });
532 }
533 
InitVsyncStation()534 void SceneSessionManager::InitVsyncStation()
535 {
536     NodeId nodeId = 0;
537     vsyncStation_ = std::make_shared<VsyncStation>(nodeId);
538 }
539 
InitScheduleUtils()540 void SceneSessionManager::InitScheduleUtils()
541 {
542 #ifdef RES_SCHED_ENABLE
543     SCBThreadInfo threadInfo = {
544         .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
545         .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
546     };
547     std::unordered_map<std::string, std::string> payload {
548         { "pid", threadInfo.scbPid_ },
549         { "tid", threadInfo.scbTid_ },
550         { "uid", threadInfo.scbUid_ },
551         { "bundleName", threadInfo.scbBundleName_ },
552     };
553     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
554     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
555     auto task = [threadInfo = std::move(threadInfo)]() mutable {
556         threadInfo.ssmThreadName_ = "OS_SceneSession";
557         threadInfo.ssmTid_ = std::to_string(gettid());
558         const int32_t userInteraction = 2;
559         std::unordered_map<std::string, std::string> payload{
560             { "pid", threadInfo.scbPid_ },
561             { "tid", threadInfo.ssmTid_ },
562             { "uid", threadInfo.scbUid_ },
563             { "extType", "10002" },
564             { "cgroupPrio", "1" },
565             { "isSa", "0" },
566             { "threadName", threadInfo.ssmThreadName_ }
567         };
568         uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
569         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
570         TLOGNI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
571         sptr<ISystemAbilityManager> systemAbilityManager =
572             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
573         if (!systemAbilityManager) {
574             TLOGNE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
575             return;
576         }
577         auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
578         int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
579         if (ret != ERR_OK) {
580             TLOGNI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
581         }
582     };
583     taskScheduler_->PostAsyncTask(task, "changeQosTask");
584 #endif
585 }
586 
UpdateSessionWithFoldStateChange(DisplayId displayId,SuperFoldStatus status,SuperFoldStatus prevStatus)587 void SceneSessionManager::UpdateSessionWithFoldStateChange(DisplayId displayId, SuperFoldStatus status,
588     SuperFoldStatus prevStatus)
589 {
590     auto task = [this, displayId, status, where = __func__]() {
591         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: status=%{public}u, display=%{public}" PRIu64,
592             where, static_cast<uint32_t>(status), displayId);
593         if (status == SuperFoldStatus::HALF_FOLDED) {
594             auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
595             if (display != nullptr) {
596                 UpdateDisplayRegion(display->GetDisplayInfo());
597             }
598         }
599         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
600         for (const auto& [_, sceneSession] : sceneSessionMap_) {
601             if (sceneSession == nullptr) {
602                 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
603                 continue;
604             }
605             sceneSession->UpdateCrossAxis();
606         }
607     };
608     taskScheduler_->PostAsyncTask(task, __func__);
609 }
610 
SetBehindWindowFilterEnabled(bool enabled)611 void SceneSessionManager::SetBehindWindowFilterEnabled(bool enabled)
612 {
613     bool isSuccessful = RSInterfaces::GetInstance().SetBehindWindowFilterEnabled(enabled);
614     TLOGI(WmsLogTag::WMS_PC, "is successful:  %{public}d", isSuccessful);
615 }
616 
RegisterAppListener()617 void SceneSessionManager::RegisterAppListener()
618 {
619     appAnrListener_ = sptr<AppAnrListener>::MakeSptr();
620     auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
621     if (appMgrClient == nullptr) {
622         TLOGE(WmsLogTag::DEFAULT, "appMgrClient is nullptr.");
623     } else {
624         auto ret = static_cast<int32_t>(appMgrClient->RegisterAppDebugListener(appAnrListener_));
625         TLOGI(WmsLogTag::DEFAULT, "Register app debug listener, %{public}d.", ret);
626     }
627 }
628 
LoadWindowParameter()629 void SceneSessionManager::LoadWindowParameter()
630 {
631     const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "HandsetSmartWindow");
632     const bool isPcMode = system::GetBoolParameter("persist.sceneboard.ispcmode", false);
633     if (multiWindowUIType == "HandsetSmartWindow") {
634         systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW;
635     } else if (multiWindowUIType == "FreeFormMultiWindow" || isPcMode) {
636         systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW;
637     } else if (multiWindowUIType == "TabletSmartWindow") {
638         systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW;
639     } else {
640         TLOGE(WmsLogTag::DEFAULT, "unknown multiWindowUIType:%{public}s.", multiWindowUIType.c_str());
641     }
642     appWindowSceneConfig_.multiWindowUIType_ = multiWindowUIType;
643 }
644 
LoadWindowSceneXml()645 void SceneSessionManager::LoadWindowSceneXml()
646 {
647     if (WindowSceneConfig::LoadConfigXml()) {
648         if (WindowSceneConfig::GetConfig().IsMap()) {
649             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
650         }
651         ConfigWindowSceneXml();
652     } else {
653         TLOGE(WmsLogTag::DEFAULT, "Load window scene xml failed");
654     }
655     ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
656         appWindowSceneConfig_.keyboardAnimationOut_);
657 }
658 
InitPrepareTerminateConfig()659 void SceneSessionManager::InitPrepareTerminateConfig()
660 {
661     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
662     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
663         PREPARE_TERMINATE_ENABLE_SIZE);
664     TLOGI(WmsLogTag::DEFAULT, "%{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
665     if (retSysParam > 0 && !std::strcmp(value, "true")) {
666         isPrepareTerminateEnable_ = true;
667     }
668 }
669 
ConfigWindowSceneXml()670 void SceneSessionManager::ConfigWindowSceneXml()
671 {
672     const auto& config = WindowSceneConfig::GetConfig();
673     WindowSceneConfig::ConfigItem item = config["windowEffect"];
674     if (item.IsMap()) {
675         ConfigWindowEffect(item);
676     }
677 
678     item = config["decor"];
679     if (item.IsMap()) {
680         ConfigDecor(item);
681     }
682 
683     item = config["backgroundswitch"];
684     int32_t param = -1;
685     systemConfig_.backgroundswitch = GetSingleIntItem(item, param) && param == 1;
686     TLOGD(WmsLogTag::DEFAULT, "Load backgroundswitch %{public}d", systemConfig_.backgroundswitch);
687     item = config["defaultWindowMode"];
688     if (GetSingleIntItem(item, param) &&
689         (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
690         param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
691         systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
692     }
693     item = config["defaultMaximizeMode"];
694     if (GetSingleIntItem(item, param) &&
695         (param == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
696          param == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
697         SceneSession::maximizeMode_ = static_cast<MaximizeMode>(param);
698     }
699     item = config["keyboardAnimation"];
700     if (item.IsMap()) {
701         ConfigKeyboardAnimation(item);
702     }
703     item = config["maxFloatingWindowSize"];
704     if (GetSingleIntItem(item, param)) {
705         systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(param);
706     }
707     item = config["windowAnimation"];
708     if (item.IsMap()) {
709         ConfigWindowAnimation(item);
710     }
711     item = config["startWindowTransitionAnimation"];
712     if (item.IsMap()) {
713         ConfigStartingWindowAnimation(item);
714     }
715     item = config["maxMidSceneNum"];
716     if (GetSingleIntItem(item, param)) {
717         systemConfig_.maxMidSceneNum_ = static_cast<uint32_t>(param);
718     }
719     ConfigFreeMultiWindow();
720     ConfigWindowSizeLimits();
721     ConfigAppsWithDeduplicatedWindowStatus();
722     ConfigSnapshotScale();
723     ConfigWindowSceneXml(config);
724 }
725 
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)726 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
727 {
728     WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
729     if (item.IsMap()) {
730         ConfigSystemUIStatusBar(item);
731     }
732     item = config["backgroundScreenLock"].GetProp("enable");
733     if (item.IsBool()) {
734         appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
735     }
736     item = config["rotationMode"];
737     if (item.IsString()) {
738         appWindowSceneConfig_.rotationMode_ = item.stringValue_;
739     }
740     item = config["immersive"];
741     if (item.IsMap()) {
742         ConfigWindowImmersive(item);
743     }
744     item = config["supportTypeFloatWindow"].GetProp("enable");
745     if (item.IsBool()) {
746         systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
747     }
748     item = config["singleHandCompatibleMode"];
749     if (item.IsMap()) {
750         ConfigSingleHandCompatibleMode(item);
751     }
752 }
753 
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)754 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
755 {
756     AppWindowSceneConfig config;
757     WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
758     if (item.IsMap()) {
759         if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
760             appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
761                 config.windowImmersive_.desktopStatusBarConfig_;
762         }
763     }
764     item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
765     if (item.IsMap()) {
766         if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
767             appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
768                 config.windowImmersive_.upDownStatusBarConfig_;
769         }
770     }
771     item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
772     if (item.IsMap()) {
773         if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
774             appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
775                 config.windowImmersive_.leftRightStatusBarConfig_;
776         }
777     }
778 }
779 
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)780 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
781     StatusBarConfig& statusBarConfig)
782 {
783     WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
784     if (item.IsBool()) {
785         statusBarConfig.showHide_ = item.boolValue_;
786     }
787     item = config["contentColor"];
788     if (item.IsString()) {
789         statusBarConfig.contentColor_ = item.stringValue_;
790     }
791     item = config["backgroundColor"];
792     if (item.IsString()) {
793         statusBarConfig.backgroundColor_ = item.stringValue_;
794     }
795     return true;
796 }
797 
ConfigFreeMultiWindow()798 void SceneSessionManager::ConfigFreeMultiWindow()
799 {
800     const auto& config = WindowSceneConfig::GetConfig();
801     WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
802     if (freeMultiWindowConfig.IsMap()) {
803         auto supportItem = freeMultiWindowConfig.GetProp("enable");
804         if (supportItem.IsBool()) {
805             systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
806         }
807         auto item = freeMultiWindowConfig["decor"];
808         if (item.IsMap()) {
809             ConfigDecor(item, false);
810         }
811         int32_t param = -1;
812         item = freeMultiWindowConfig["defaultWindowMode"];
813         if (GetSingleIntItem(item, param) &&
814             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
815              param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
816             systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
817                 static_cast<WindowMode>(static_cast<uint32_t>(param));
818         }
819         item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
820         if (GetSingleIntItem(item, param) && (param > 0)) {
821             systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
822         }
823         param = -1;
824         item = freeMultiWindowConfig["defaultDragResizeType"];
825         if (GetSingleIntItem(item, param) && param >= 0 &&
826             param < static_cast<int32_t>(DragResizeType::RESIZE_MAX_VALUE)) {
827             systemConfig_.freeMultiWindowConfig_.defaultDragResizeType_ =
828                 static_cast<DragResizeType>(static_cast<uint32_t>(param));
829         }
830     }
831 }
832 
LoadFreeMultiWindowConfig(bool enable)833 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
834 {
835     FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
836     if (enable) {
837         systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
838         systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
839         systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
840     } else {
841         const auto& config = WindowSceneConfig::GetConfig();
842         auto item = config["decor"];
843         if (item.IsMap()) {
844             ConfigDecor(item, true);
845         }
846         int32_t param = -1;
847         item = config["defaultWindowMode"];
848         if (GetSingleIntItem(item, param) &&
849             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
850              param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
851             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
852         }
853     }
854     systemConfig_.freeMultiWindowEnable_ = enable;
855     rsInterface_.SetFreeMultiWindowStatus(enable);
856 }
857 
GetSystemSessionConfig() const858 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
859 {
860     return systemConfig_;
861 }
862 
SwitchFreeMultiWindow(bool enable)863 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
864 {
865     if (!systemConfig_.freeMultiWindowSupport_) {
866         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "device not support");
867         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
868     }
869     LoadFreeMultiWindowConfig(enable);
870     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
871     for (const auto& [_, sceneSession] : sceneSessionMap_) {
872         if (sceneSession == nullptr) {
873             continue;
874         }
875         sceneSession->SwitchFreeMultiWindow(systemConfig_);
876     }
877     UpdateAppHookWindowInfoWhenSwitchFreeMultiWindow(enable);
878     WindowStyleType type = enable ?
879             WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
880     SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
881     return WSError::WS_OK;
882 }
883 
GetFreeMultiWindowEnableState(bool & enable)884 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
885 {
886     enable = systemConfig_.freeMultiWindowEnable_;
887     return WSError::WS_OK;
888 }
889 
SetForegroundWindowNum(uint32_t windowNum)890 WMError SceneSessionManager::SetForegroundWindowNum(uint32_t windowNum)
891 {
892     if (!SessionPermission::IsSystemServiceCalling()) {
893         TLOGE(WmsLogTag::WMS_PC, "The caller is not system service.");
894         return WMError::WM_ERROR_INVALID_PERMISSION;
895     }
896     if (!systemConfig_.freeMultiWindowSupport_) {
897         TLOGE(WmsLogTag::WMS_PC, "device not support");
898         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
899     }
900     taskScheduler_->PostAsyncTask([this, windowNum]() {
901         if (setForegroundWindowNumFunc_) {
902             TLOGNI(WmsLogTag::WMS_PC, "max foreground windowNum: %{public}d", windowNum);
903             setForegroundWindowNumFunc_(windowNum);
904         }
905     }, __func__);
906     return WMError::WM_OK;
907 }
908 
RegisterSetForegroundWindowNumCallback(SetForegroundWindowNumFunc && func)909 void SceneSessionManager::RegisterSetForegroundWindowNumCallback(SetForegroundWindowNumFunc&& func)
910 {
911     setForegroundWindowNumFunc_ = std::move(func);
912 }
913 
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)914 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject>& token,
915     const ContinueState& continueState)
916 {
917     TLOGI(WmsLogTag::WMS_LIFE, "in");
918     int32_t callingUid = IPCSkeleton::GetCallingUid();
919     return taskScheduler_->PostSyncTask([this, token, continueState, callingUid, where = __func__] {
920         sptr <SceneSession> sceneSession = FindSessionByToken(token);
921         if (sceneSession == nullptr) {
922             TLOGNE(WmsLogTag::DEFAULT, "fail to find session by token.");
923             return WSError::WS_ERROR_INVALID_PARAM;
924         }
925         sceneSession->SetSessionInfoContinueState(continueState);
926         DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
927             static_cast<AAFwk::ContinueState>(continueState), callingUid);
928         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id:%{public}d, continueState:%{public}d",
929             where, sceneSession->GetPersistentId(), continueState);
930         return WSError::WS_OK;
931     }, __func__);
932 }
933 
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)934 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
935 {
936     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
937     if (item.IsBool()) {
938         if (mainConfig) {
939             systemConfig_.isSystemDecorEnable_ = item.boolValue_;
940         } else {
941             systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
942         }
943         bool decorEnable = item.boolValue_;
944         uint32_t support = 0;
945         std::vector<std::string> supportedModes;
946         item = decorConfig["supportedMode"];
947         if (item.IsStrings()) {
948             supportedModes = *item.stringsValue_;
949         }
950         for (auto mode : supportedModes) {
951             if (mode == "fullscreen") {
952                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
953             } else if (mode == "floating") {
954                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
955             } else if (mode == "pip") {
956                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
957             } else if (mode == "split") {
958                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
959                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
960             } else if (mode == "fb") {
961                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FB;
962             } else {
963                 TLOGW(WmsLogTag::DEFAULT, "Invalid supporedMode");
964                 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
965                 break;
966             }
967         }
968         if (mainConfig && item.IsStrings()) {
969             systemConfig_.decorWindowModeSupportType_ = support;
970         }
971         if (!mainConfig && item.IsStrings()) {
972             systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
973         }
974     }
975 }
976 
AddAlphaToColor(float alpha,std::string & color)977 static void AddAlphaToColor(float alpha, std::string& color)
978 {
979     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
980         return;
981     }
982 
983     uint32_t alphaValue = 0xFF * alpha;
984     std::ostringstream ss;
985     ss << std::hex << alphaValue;
986     std::string strAlpha = ss.str();
987     if (strAlpha.size() == 1) {
988         strAlpha.append(1, '0');
989     }
990 
991     color.insert(1, strAlpha);
992 }
993 
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)994 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
995 {
996     return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
997         (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) == AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
998 }
999 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)1000 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
1001 {
1002     AppWindowSceneConfig config;
1003     // config corner radius
1004     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
1005     if (item.IsMap()) {
1006         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
1007             appWindowSceneConfig_ = config;
1008             // set default corner radius of window by system config
1009             systemConfig_.defaultCornerRadius_ = config.floatCornerRadius_;
1010         }
1011     }
1012 
1013     // config shadow
1014     item = effectConfig["appWindows"]["shadow"]["focused"];
1015     if (item.IsMap()) {
1016         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
1017             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
1018         }
1019     }
1020     item = effectConfig["appWindows"]["shadow"]["unfocused"];
1021     if (item.IsMap()) {
1022         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
1023             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
1024         }
1025     }
1026     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
1027     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
1028 
1029     // config shadow in dark mode
1030     item = effectConfig["appWindows"]["shadowDark"]["focused"];
1031     if (item.IsMap()) {
1032         if (ConfigAppWindowShadow(item, config.focusedShadowDark_)) {
1033             appWindowSceneConfig_.focusedShadowDark_ = config.focusedShadowDark_;
1034         }
1035     }
1036     item = effectConfig["appWindows"]["shadowDark"]["unfocused"];
1037     if (item.IsMap()) {
1038         if (ConfigAppWindowShadow(item, config.unfocusedShadowDark_)) {
1039             appWindowSceneConfig_.unfocusedShadowDark_ = config.unfocusedShadowDark_;
1040         }
1041     }
1042     AddAlphaToColor(appWindowSceneConfig_.focusedShadowDark_.alpha_, appWindowSceneConfig_.focusedShadowDark_.color_);
1043     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadowDark_.alpha_,
1044         appWindowSceneConfig_.unfocusedShadowDark_.color_);
1045 
1046     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "successfully");
1047 }
1048 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)1049 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
1050 {
1051     static const std::unordered_map<std::string, float> stringToCornerRadius = {
1052         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
1053         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
1054     };
1055 
1056     if (item.IsString()) {
1057         auto value = item.stringValue_;
1058         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
1059             out = stringToCornerRadius.at(value);
1060             return true;
1061         }
1062     }
1063     return false;
1064 }
1065 
SetEnableInputEvent(bool enabled)1066 void SceneSessionManager::SetEnableInputEvent(bool enabled)
1067 {
1068     TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
1069     enableInputEvent_ = enabled;
1070 
1071     if (recoverStateChangeFunc_ == nullptr) {
1072         return;
1073     }
1074 
1075     if (enabled) {
1076         recoverStateChangeFunc_(RecoverState::RECOVER_ENABLE_INPUT);
1077     } else {
1078         recoverStateChangeFunc_(RecoverState::RECOVER_INITIAL);
1079     }
1080 
1081 }
1082 
IsInputEventEnabled() const1083 bool SceneSessionManager::IsInputEventEnabled() const
1084 {
1085     return enableInputEvent_;
1086 }
1087 
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)1088 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
1089 {
1090     for (const auto persistentId : alivePersistentIds_) {
1091         if (std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId) !=
1092             recoveredPersistentIds.end()) {
1093             continue;
1094         }
1095         auto sceneSession = GetSceneSession(persistentId);
1096         if (sceneSession == nullptr) {
1097             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
1098             continue;
1099         }
1100         if (sceneSession->IsRecovered()) {
1101             TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
1102             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1103             visibleWindowCountMap_.erase(sceneSession->GetCallingPid());
1104             EraseSceneSessionAndMarkDirtyLocked(persistentId);
1105             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
1106                 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
1107                 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
1108             }
1109         }
1110     }
1111 }
1112 
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)1113 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
1114 {
1115     TLOGI(WmsLogTag::WMS_RECOVER, "persistentIds recovered=%{public}zu. CurrentUserId=%{public}d",
1116         recoveredPersistentIds.size(), currentUserId_.load());
1117 
1118     taskScheduler_->PostAsyncTask([this, recoveredPersistentIds]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
1119         ClearUnrecoveredSessions(recoveredPersistentIds);
1120         std::list<AAFwk::SessionInfo> abilitySessionInfos;
1121         for (const auto persistentId : recoveredPersistentIds) {
1122             if (failRecoveredPersistentIdSet_.count(persistentId)) {
1123                 TLOGNI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId=%{public}d, continue", persistentId);
1124                 continue;
1125             }
1126             auto sceneSession = GetSceneSession(persistentId);
1127             if (sceneSession == nullptr) {
1128                 TLOGNE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
1129                 continue;
1130             }
1131             const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
1132             TLOGND(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d", persistentId);
1133             abilitySessionInfos.emplace_back(*abilitySessionInfo);
1134         }
1135         std::vector<int32_t> unrecoverableSessionIds;
1136         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
1137             abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
1138         TLOGNI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds=%{public}zu",
1139             unrecoverableSessionIds.size());
1140         for (const auto sessionId : unrecoverableSessionIds) {
1141             auto sceneSession = GetSceneSession(sessionId);
1142             if (sceneSession == nullptr) {
1143                 TLOGNW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId=%{public}d ",
1144                     sessionId);
1145                 continue;
1146             }
1147             const auto& sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
1148             TLOGNI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId=%{public}d", sessionId);
1149             ExceptionInfo exceptionInfo;
1150             sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo);
1151         }
1152         RemoveFailRecoveredSession();
1153     }, __func__);
1154 }
1155 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)1156 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
1157     WindowShadowConfig& outShadow)
1158 {
1159     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
1160     if (item.IsString()) {
1161         auto color = item.stringValue_;
1162         uint32_t colorValue;
1163         if (!ColorParser::Parse(color, colorValue)) {
1164             return false;
1165         }
1166         outShadow.color_ = color;
1167     }
1168 
1169     item = shadowConfig["offsetX"];
1170     if (item.IsFloats()) {
1171         auto offsetX = *item.floatsValue_;
1172         if (offsetX.size() != 1) {
1173             return false;
1174         }
1175         outShadow.offsetX_ = offsetX[0];
1176     }
1177 
1178     item = shadowConfig["offsetY"];
1179     if (item.IsFloats()) {
1180         auto offsetY = *item.floatsValue_;
1181         if (offsetY.size() != 1) {
1182             return false;
1183         }
1184         outShadow.offsetY_ = offsetY[0];
1185     }
1186 
1187     item = shadowConfig["alpha"];
1188     if (item.IsFloats()) {
1189         auto alpha = *item.floatsValue_;
1190         if (alpha.size() != 1 ||
1191             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
1192             return false;
1193         }
1194         outShadow.alpha_ = alpha[0];
1195     }
1196 
1197     item = shadowConfig["radius"];
1198     if (item.IsFloats()) {
1199         auto radius = *item.floatsValue_;
1200         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
1201             return false;
1202         }
1203         outShadow.radius_ = radius[0];
1204     }
1205 
1206     return true;
1207 }
1208 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)1209 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
1210     KeyboardSceneAnimationConfig& config)
1211 {
1212     if (item.IsMap() && item.mapValue_->count("curve")) {
1213         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1214         config.curveType_ = curveType;
1215         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1216             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1217             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1218             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1219             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1220         }
1221     }
1222 
1223     const WindowSceneConfig::ConfigItem& duration = item["duration"];
1224     if (duration.IsInts()) {
1225         auto numbers = *duration.intsValue_;
1226         if (numbers.size() == 1) {
1227             config.duration_ = static_cast<uint32_t>(numbers[0]);
1228         }
1229     }
1230 }
1231 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)1232 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
1233 {
1234     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
1235     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
1236 
1237     // config system animation
1238     const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
1239     systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
1240         {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
1241         appConfigIn.duration_);
1242     const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
1243     systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
1244         {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
1245         appConfigOut.duration_);
1246 }
1247 
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)1248 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
1249     KeyboardSceneAnimationConfig& animationOut)
1250 {
1251     if (!systemConfig_.animationIn_.curveType_.empty() && !systemConfig_.animationOut_.curveType_.empty()) {
1252         TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
1253             "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
1254             systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
1255             systemConfig_.animationOut_.duration_);
1256         return;
1257     }
1258 
1259     // default animation curve params
1260     constexpr char CURVETYPE[] = "interpolatingSpring";
1261     constexpr float IN_CTRLX1 = 0.0f;
1262     constexpr float OUT_CTRLX1 = 4.0f;
1263     constexpr float CTRLY1 = 1.0f;
1264     constexpr float CTRLX2 = 342.0f;
1265     constexpr float CTRLY2 = 37.0f;
1266     constexpr uint32_t DURATION = 150;
1267 
1268     if (systemConfig_.animationIn_.curveType_.empty()) {
1269         std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1270         // update system config for client
1271         systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1272         // update app config for server
1273         animationIn.curveType_ = CURVETYPE;
1274         animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1275         animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1276         animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1277         animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1278         animationIn.duration_ = DURATION;
1279         TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationIn");
1280     }
1281 
1282     if (systemConfig_.animationOut_.curveType_.empty()) {
1283         std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1284         // update system config for client
1285         systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1286         // update app config for server
1287         animationOut.curveType_ = CURVETYPE;
1288         animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1289         animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1290         animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1291         animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1292         animationOut.duration_ = DURATION;
1293         TLOGI(WmsLogTag::WMS_KEYBOARD, "config default animationOut");
1294     }
1295 }
1296 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1297 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1298 {
1299     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1300     if (item.IsMap() && item.mapValue_->count("curve")) {
1301         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1302         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1303         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1304             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1305             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1306             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1307             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1308         }
1309     }
1310     item = windowAnimationConfig["timing"]["duration"];
1311     if (item.IsInts() && item.intsValue_->size() == 1) {
1312         auto duration = *item.intsValue_;
1313         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1314     }
1315     item = windowAnimationConfig["scale"];
1316     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1317         auto scales = *item.floatsValue_;
1318         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1319         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1320     }
1321     item = windowAnimationConfig["rotation"];
1322     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1323         auto rotations = *item.floatsValue_;
1324         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1325         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1326         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1327         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1328     }
1329     item = windowAnimationConfig["translate"];
1330     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1331         auto translates = *item.floatsValue_;
1332         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1333         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1334     }
1335     item = windowAnimationConfig["opacity"];
1336     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1337         auto opacity = *item.floatsValue_;
1338         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1339     }
1340 }
1341 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1342 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1343 {
1344     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1345     auto item = configItem.GetProp("enable");
1346     if (item.IsBool()) {
1347         config.enabled_ = item.boolValue_;
1348     }
1349     item = configItem["timing"];
1350     if (item.IsMap() && item.mapValue_->count("curve")) {
1351         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1352     }
1353     item = configItem["timing"]["duration"];
1354     if (item.IsInts() && item.intsValue_->size() == 1) {
1355         config.duration_ = (*item.intsValue_)[0];
1356     }
1357     item = configItem["opacityStart"];
1358     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1359         config.opacityStart_ = (*item.floatsValue_)[0];
1360     }
1361     item = configItem["opacityEnd"];
1362     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1363         config.opacityEnd_ = (*item.floatsValue_)[0];
1364     }
1365 }
1366 
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1367 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1368     const WindowSceneConfig::ConfigItem& curveConfig)
1369 {
1370     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1371         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1372     static std::unordered_set<std::string> paramCurveSet = {
1373         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1374 
1375     std::string curveName = "easeOut";
1376     const auto& nameItem = curveConfig.GetProp("name");
1377     if (!nameItem.IsString()) {
1378         return {curveName, {}};
1379     }
1380 
1381     std::string name = nameItem.stringValue_;
1382     std::vector<float> curveParams;
1383 
1384     if (paramCurveSet.find(name) != paramCurveSet.end()) {
1385         curveName = name;
1386         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1387         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1388             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1389                 curveParams.begin());
1390         }
1391     } else {
1392         auto iter = curveSet.find(name);
1393         if (iter != curveSet.end()) {
1394             curveName = name;
1395         }
1396     }
1397 
1398     return {curveName, curveParams};
1399 }
1400 
1401 
ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem & configItem)1402 void SceneSessionManager::ConfigSingleHandCompatibleMode(const WindowSceneConfig::ConfigItem& configItem)
1403 {
1404     auto& config = singleHandCompatibleModeConfig_;
1405     auto item = configItem.GetProp("enable");
1406     if (item.IsBool()) {
1407         config.enabled = item.boolValue_;
1408     }
1409     item = configItem["singleHandScale"];
1410     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1411         config.singleHandScale = (*item.floatsValue_)[0];
1412     }
1413     item = configItem["heightChangeRatio"];
1414     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1415         config.heightChangeRatio = (*item.floatsValue_)[0];
1416     }
1417     item = configItem["widthChangeRatio"];
1418     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1419         config.widthChangeRatio = (*item.floatsValue_)[0];
1420     }
1421 }
1422 
ConfigAppsWithDeduplicatedWindowStatus()1423 void SceneSessionManager::ConfigAppsWithDeduplicatedWindowStatus()
1424 {
1425     const auto& config = WindowSceneConfig::GetConfig();
1426     WindowSceneConfig::ConfigItem item = config["appsWithDeduplicatedWindowStatus"];
1427     std::vector<std::string> appsWithDeduplicatedWindowStatus;
1428     if (item.IsStrings()) {
1429         appsWithDeduplicatedWindowStatus = *item.stringsValue_;
1430     }
1431     for (auto&& app : appsWithDeduplicatedWindowStatus) {
1432         if (!app.empty()) {
1433             TLOGI(WmsLogTag::WMS_LAYOUT, "app:%{public}s", app.c_str());
1434             appsWithDeduplicatedWindowStatus_.insert(std::move(app));
1435         }
1436     }
1437 }
1438 
SetWindowStatusDeduplicationBySystemConfig(const SessionInfo & sessionInfo,SystemSessionConfig & systemConfig)1439 void SceneSessionManager::SetWindowStatusDeduplicationBySystemConfig(const SessionInfo& sessionInfo,
1440     SystemSessionConfig& systemConfig)
1441 {
1442     std::string bundleName = sessionInfo.bundleName_;
1443     bool deduplicationEnabled = false;
1444     if (appsWithDeduplicatedWindowStatus_.find(bundleName) != appsWithDeduplicatedWindowStatus_.end()) {
1445         TLOGI(WmsLogTag::WMS_LAYOUT, "need skip redundant windowStatus notifications, name:%{public}s",
1446             bundleName.c_str());
1447         deduplicationEnabled = true;
1448     }
1449     systemConfig.skipRedundantWindowStatusNotifications_ = deduplicationEnabled;
1450 }
1451 
ConfigWindowSizeLimits()1452 void SceneSessionManager::ConfigWindowSizeLimits()
1453 {
1454     const auto& config = WindowSceneConfig::GetConfig();
1455     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1456     if (item.IsMap()) {
1457         ConfigMainWindowSizeLimits(item);
1458     }
1459 
1460     item = config["subWindowSizeLimits"];
1461     if (item.IsMap()) {
1462         ConfigSubWindowSizeLimits(item);
1463     }
1464 
1465     item = config["dialogWindowSizeLimits"];
1466     if (item.IsMap()) {
1467         ConfigDialogWindowSizeLimits(item);
1468     }
1469 }
1470 
ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem & dialogWindowSizeConifg)1471 void SceneSessionManager::ConfigDialogWindowSizeLimits(const WindowSceneConfig::ConfigItem& dialogWindowSizeConifg)
1472 {
1473     auto item = dialogWindowSizeConifg["miniWidth"];
1474     if (item.IsInts()) {
1475         auto numbers = *item.intsValue_;
1476         if (numbers.size() == 1) {
1477             systemConfig_.miniWidthOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1478         }
1479     }
1480 
1481     item = dialogWindowSizeConifg["miniHeight"];
1482     if (item.IsInts()) {
1483         auto numbers = *item.intsValue_;
1484         if (numbers.size() == 1) {
1485             systemConfig_.miniHeightOfDialogWindow_ = static_cast<uint32_t>(numbers[0]);
1486         }
1487     }
1488 }
1489 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1490 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1491 {
1492     auto item = mainWindowSizeConifg["miniWidth"];
1493     if (item.IsInts()) {
1494         auto numbers = *item.intsValue_;
1495         if (numbers.size() == 1) {
1496             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1497         }
1498     }
1499 
1500     item = mainWindowSizeConifg["miniHeight"];
1501     if (item.IsInts()) {
1502         auto numbers = *item.intsValue_;
1503         if (numbers.size() == 1) {
1504             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1505         }
1506     }
1507 }
1508 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1509 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1510 {
1511     auto item = subWindowSizeConifg["miniWidth"];
1512     if (item.IsInts()) {
1513         auto numbers = *item.intsValue_;
1514         if (numbers.size() == 1) {
1515             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1516         }
1517     }
1518 
1519     item = subWindowSizeConifg["miniHeight"];
1520     if (item.IsInts()) {
1521         auto numbers = *item.intsValue_;
1522         if (numbers.size() == 1) {
1523             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1524         }
1525     }
1526 }
1527 
ConfigSnapshotScale()1528 void SceneSessionManager::ConfigSnapshotScale()
1529 {
1530     const auto& config = WindowSceneConfig::GetConfig();
1531     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1532     if (item.IsFloats()) {
1533         auto snapshotScale = *item.floatsValue_;
1534         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1535             return;
1536         }
1537         snapshotScale_ = snapshotScale[0];
1538     }
1539 }
1540 
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1541 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1542 {
1543     TLOGI(WmsLogTag::WMS_IMMS, "load");
1544     WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1545     if (item.IsInts() && item.intsValue_->size() == 1) {
1546         bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1547         appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1548         TLOGI(WmsLogTag::WMS_IMMS, "showInLandscapeMode %{public}d",
1549             appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1550     }
1551 
1552     item = statusBarConfig["immersiveStatusBarBgColor"];
1553     if (item.IsString()) {
1554         auto color = item.stringValue_;
1555         uint32_t colorValue;
1556         if (!ColorParser::Parse(color, colorValue)) {
1557             return;
1558         }
1559         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1560         TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarBgColor %{public}s",
1561             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1562     }
1563 
1564     item = statusBarConfig["immersiveStatusBarContentColor"];
1565     if (item.IsString()) {
1566         auto color = item.stringValue_;
1567         uint32_t colorValue;
1568         if (!ColorParser::Parse(color, colorValue)) {
1569             return;
1570         }
1571         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1572         TLOGI(WmsLogTag::WMS_IMMS, "immersiveStatusBarContentColor %{public}s",
1573             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1574     }
1575 }
1576 
ConfigSupportFollowParentWindowLayout()1577 void SceneSessionManager::ConfigSupportFollowParentWindowLayout()
1578 {
1579     TLOGI(WmsLogTag::WMS_SUB, "support");
1580     auto task = [this] {
1581         systemConfig_.supportFollowParentWindowLayout_ = true;
1582     };
1583     taskScheduler_->PostAsyncTask(task, "ConfigSupportFollowParentWindowLayout");
1584 }
1585 
ConfigSupportFollowRelativePositionToParent()1586 void SceneSessionManager::ConfigSupportFollowRelativePositionToParent()
1587 {
1588     TLOGI(WmsLogTag::WMS_SUB, "support");
1589     auto task = [this] {
1590         systemConfig_.supportFollowRelativePositionToParent_ = true;
1591     };
1592     taskScheduler_->PostAsyncTask(task, "ConfigSupportFollowRelativePositionToParent");
1593 }
1594 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1595 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1596 {
1597     rootSceneContextWeak_ = contextWeak;
1598 }
1599 
CreateRootSceneSession()1600 void SceneSessionManager::CreateRootSceneSession()
1601 {
1602     system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1603     auto specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1604     specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1605         return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1606     };
1607     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1608         return this->GetSceneSessionVectorByType(type);
1609     };
1610     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1611         return this->GetAINavigationBarArea(displayId);
1612     };
1613     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1614         this->UpdateAvoidArea(persistentId);
1615     };
1616     specificCb->onNotifyAvoidAreaChange_ = [this](const sptr<AvoidArea>& avoidArea, AvoidAreaType type) {
1617         onNotifyAvoidAreaChangeForRootFunc_(avoidArea, type, nullptr);
1618     };
1619     rootSceneSession_ = sptr<RootSceneSession>::MakeSptr(specificCb);
1620     rootSceneSession_->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1621     rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1622     rootSceneSession_->SetSystemConfig(systemConfig_);
1623 
1624     AppExecFwk::RunningProcessInfo info;
1625     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(getpid(), info);
1626     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d processName: %{public}s", getpid(), info.processName_.c_str());
1627 
1628     if (SCENE_BOARD_BUNDLE_NAME == info.processName_) {
1629         AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1630         TLOGI(WmsLogTag::WMS_LIFE, "SetRootSceneSession success.");
1631     }
1632 
1633     rootSceneSession_->RegisterGetStatusBarAvoidHeightFunc([this](DisplayId displayId, WSRect& barArea) {
1634         return this->GetStatusBarAvoidHeight(displayId, barArea);
1635     });
1636     rootSceneSession_->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
1637         return this->GetStatusBarConstantlyShow(displayId, isVisible);
1638     });
1639 }
1640 
GetRootSceneSession()1641 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1642 {
1643     return rootSceneSession_;
1644 }
1645 
UpdateRootSceneAvoidArea()1646 void SceneSessionManager::UpdateRootSceneAvoidArea()
1647 {
1648     UpdateAvoidArea(rootSceneSession_->GetPersistentId());
1649 }
1650 
RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc && func)1651 void SceneSessionManager::RegisterNotifyRootSceneAvoidAreaChangeFunc(NotifyRootSceneAvoidAreaChangeFunc&& func)
1652 {
1653     onNotifyAvoidAreaChangeForRootFunc_ = std::move(func);
1654 }
1655 
GetRootSessionAvoidAreaByType(AvoidAreaType type)1656 AvoidArea SceneSessionManager::GetRootSessionAvoidAreaByType(AvoidAreaType type)
1657 {
1658     if (auto rootSession = GetRootSceneSession()) {
1659         return rootSession->GetAvoidAreaByType(type);
1660     }
1661     return {};
1662 }
1663 
GetRootSceneStatusBarHeight() const1664 uint32_t SceneSessionManager::GetRootSceneStatusBarHeight() const
1665 {
1666     return static_cast<uint32_t>(rootSceneSession_->GetStatusBarHeight());
1667 }
1668 
GetSceneSession(int32_t persistentId)1669 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1670 {
1671     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1672     if (auto it = sceneSessionMap_.find(persistentId); it != sceneSessionMap_.end()) {
1673         return it->second;
1674     }
1675     TLOGD(WmsLogTag::DEFAULT, "Not found scene session with id: %{public}d", persistentId);
1676     return nullptr;
1677 }
1678 
IsMainWindowByPersistentId(int32_t persistentId)1679 bool SceneSessionManager::IsMainWindowByPersistentId(int32_t persistentId)
1680 {
1681     if (persistentId <= INVALID_SESSION_ID) {
1682         return false;
1683     }
1684     if (auto sceneSession = GetSceneSession(persistentId)) {
1685         return SessionHelper::IsMainWindow(sceneSession->GetWindowType());
1686     }
1687     return false;
1688 }
1689 
GetMainSessionByPersistentId(int32_t persistentId) const1690 sptr<SceneSession> SceneSessionManager::GetMainSessionByPersistentId(int32_t persistentId) const
1691 {
1692     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1693     auto it = sceneSessionMap_.find(persistentId);
1694     if (it != sceneSessionMap_.end() && it->second && SessionHelper::IsMainWindow(it->second->GetWindowType())) {
1695         return it->second;
1696     }
1697     return nullptr;
1698 }
1699 
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1700 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1701     const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1702 {
1703     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1704     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1705         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1706             sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1707             SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1708             mainSessions.push_back(sceneSession);
1709         }
1710     }
1711 }
1712 
GetMainSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,std::vector<sptr<SceneSession>> & mainSessions) const1713 void SceneSessionManager::GetMainSessionByAbilityInfo(const AbilityInfoBase& abilityInfo,
1714     std::vector<sptr<SceneSession>>& mainSessions) const
1715 {
1716     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1717     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1718         if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1719             continue;
1720         }
1721         if (sceneSession->GetSessionInfo().bundleName_ == abilityInfo.bundleName &&
1722             sceneSession->GetSessionInfo().moduleName_ == abilityInfo.moduleName &&
1723             sceneSession->GetSessionInfo().abilityName_ == abilityInfo.abilityName &&
1724             sceneSession->GetSessionInfo().appIndex_ == abilityInfo.appIndex) {
1725             mainSessions.push_back(sceneSession);
1726         }
1727     }
1728 }
1729 
GetSceneSessionByIdentityInfo(const SessionIdentityInfo & info)1730 sptr<SceneSession> SceneSessionManager::GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)
1731 {
1732     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1733     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1734         if (!sceneSession) {
1735             return nullptr;
1736         }
1737         if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1738             sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1739             sceneSession->GetSessionInfo().appInstanceKey_ != info.instanceKey_ ||
1740             sceneSession->GetSessionInfo().specifiedFlag_ != info.specifiedFlag_ ||
1741             sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1742             continue;
1743         }
1744         const auto& sessionModuleName = sceneSession->GetSessionInfo().moduleName_;
1745         const auto& sessionAbilityName = sceneSession->GetSessionInfo().abilityName_;
1746         if (info.isAtomicService_) {
1747             if ((sessionModuleName.empty() || sessionModuleName == info.moduleName_) &&
1748                 (sessionAbilityName.empty() || sessionAbilityName == info.abilityName_)) {
1749                 return sceneSession;
1750             }
1751         } else if (sessionModuleName == info.moduleName_ && sessionAbilityName == info.abilityName_) {
1752             return sceneSession;
1753         }
1754     }
1755     return nullptr;
1756 }
1757 
GetSceneSessionByType(WindowType type)1758 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1759 {
1760     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1761     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1762         if (sceneSession && sceneSession->GetWindowType() == type) {
1763             return sceneSession;
1764         }
1765     }
1766     return nullptr;
1767 }
1768 
GetSceneSessionByBundleName(const std::string & bundleName)1769 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1770 {
1771     std::vector<sptr<SceneSession>> sceneSessionVector;
1772     if (bundleName.empty()) {
1773         return sceneSessionVector;
1774     }
1775     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1776     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1777         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1778             sceneSessionVector.emplace_back(sceneSession);
1779         }
1780     }
1781     return sceneSessionVector;
1782 }
1783 
GetSceneSessionVectorByTypeAndDisplayId(WindowType type,uint64_t displayId)1784 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByTypeAndDisplayId(
1785     WindowType type, uint64_t displayId)
1786 {
1787     if (displayId == DISPLAY_ID_INVALID) {
1788         TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1789         return {};
1790     }
1791     std::vector<sptr<SceneSession>> sceneSessionVector;
1792     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1793     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1794         if (sceneSession->GetWindowType() == type &&
1795             sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1796             sceneSessionVector.emplace_back(sceneSession);
1797         }
1798     }
1799     return sceneSessionVector;
1800 }
1801 
GetSceneSessionVectorByType(WindowType type)1802 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
1803 {
1804     std::vector<sptr<SceneSession>> sceneSessionVector;
1805     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1806     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1807         if (sceneSession->GetWindowType() == type) {
1808             sceneSessionVector.emplace_back(sceneSession);
1809         }
1810     }
1811     return sceneSessionVector;
1812 }
1813 
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1814 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1815     sptr<WindowSessionProperty> property)
1816 {
1817     if (sceneSession == nullptr || property == nullptr) {
1818         TLOGD(WmsLogTag::WMS_DIALOG, "Session or property is null");
1819         return WSError::WS_ERROR_NULLPTR;
1820     }
1821     auto parentPersistentId = property->GetParentPersistentId();
1822     sceneSession->SetParentPersistentId(parentPersistentId);
1823     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1824         auto parentSession = GetSceneSession(parentPersistentId);
1825         if (parentSession == nullptr) {
1826             TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1827             return WSError::WS_ERROR_NULLPTR;
1828         }
1829         sceneSession->GetSessionProperty()->SetSubWindowZLevel(property->GetSubWindowZLevel());
1830         parentSession->BindDialogSessionTarget(sceneSession);
1831         parentSession->BindDialogToParentSession(sceneSession);
1832         sceneSession->SetParentSession(parentSession);
1833         TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1834             sceneSession->GetPersistentId(), parentPersistentId);
1835     }
1836     return WSError::WS_OK;
1837 }
1838 
CreateSpecificSessionCallback()1839 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1840 {
1841     sptr<SceneSession::SpecificSessionCallback> specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1842     specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1843         return this->RequestSceneSession(sessionInfo, property);
1844     };
1845     specificCb->onDestroy_ = [this](const int32_t persistentId) {
1846         return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1847     };
1848     specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1849         this->ClearDisplayStatusBarTemporarilyFlags();
1850     };
1851     specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1852         this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1853     };
1854     specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1855         return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1856     };
1857     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1858         return this->GetSceneSessionVectorByType(type);
1859     };
1860     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1861         this->UpdateAvoidArea(persistentId);
1862     };
1863     specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1864         return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1865     };
1866     specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1867         this->NotifyWindowInfoChange(persistentId, type);
1868     };
1869     specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1870         this->NotifyMMIWindowPidChange(windowId, startMoving);
1871     };
1872     specificCb->onSessionTouchOutside_ = [this](int32_t persistentId, DisplayId displayId) {
1873         this->NotifySessionTouchOutside(persistentId, displayId);
1874     };
1875     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1876         return this->GetAINavigationBarArea(displayId);
1877     };
1878     specificCb->onGetNextAvoidAreaRectInfo_ = [this](
1879         DisplayId displayId, AvoidAreaType type, std::pair<WSRect, WSRect>& nextSystemBarAvoidAreaRectInfo) {
1880         return this->GetNextAvoidRectInfo(displayId, type, nextSystemBarAvoidAreaRectInfo);
1881     };
1882     specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1883         this->OnOutsideDownEvent(x, y);
1884     };
1885     specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1886         return this->HandleSecureSessionShouldHide(sceneSession);
1887     };
1888     specificCb->onNotifyWindowSystemBarPropertyChangeFunc_ = [this](
1889         WindowType type, const SystemBarProperty& systemBarProperty) {
1890         return this->NotifyWindowSystemBarPropertyChange(type, systemBarProperty);
1891     };
1892     specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1893         this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1894     };
1895     specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1896         this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1897     };
1898     specificCb->onSetSkipEventOnCastPlus_ = [this](int32_t windowId, bool isSkip) {
1899         this->SetSkipEventOnCastPlusInner(windowId, isSkip);
1900     };
1901     specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1902         this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1903     };
1904     specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1905         this->UpdateGestureBackEnabled(persistentId);
1906     };
1907     specificCb->onKeyboardRotationChange_ = [this](int32_t persistentId, Rotation rotation,
1908         std::vector<std::pair<bool, WSRect>>& avoidAreas) {
1909         this->GetKeyboardOccupiedAreaWithRotation(persistentId, rotation, avoidAreas);
1910     };
1911     specificCb->onGetSceneSessionByIdCallback_ = [this](int32_t persistentId) {
1912         return this->GetSceneSession(persistentId);
1913     };
1914     return specificCb;
1915 }
1916 
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1917 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1918 {
1919     TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1920     auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1921     if (isSkip) {
1922         if (it == skipSurfaceNodeIds_.end()) {
1923             skipSurfaceNodeIds_.push_back(surfaceNodeId);
1924         } else {
1925             return;
1926         }
1927     } else {
1928         if (it != skipSurfaceNodeIds_.end()) {
1929             skipSurfaceNodeIds_.erase(it);
1930         } else {
1931             return;
1932         }
1933     }
1934     rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1935 }
1936 
AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1937 WMError SceneSessionManager::AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1938 {
1939     if (!SessionPermission::IsSystemCalling()) {
1940         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
1941         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1942     }
1943     auto task = [this, &persistentIds] {
1944         for (const auto persistentId : persistentIds) {
1945             auto session = GetSceneSession(persistentId);
1946             if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1947                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1948                 continue;
1949             }
1950             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] add to virtual screen black list", persistentId);
1951             auto surfaceNode = session->GetSurfaceNode();
1952             if (surfaceNode) {
1953                 auto surfaceNodeId = surfaceNode->GetId();
1954                 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId) == 0) {
1955                     skipSurfaceNodeIds_.push_back(surfaceNodeId);
1956                 }
1957             }
1958             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1959             if (leashWinSurfaceNode) {
1960                 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1961                 if (std::count(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId) == 0) {
1962                     skipSurfaceNodeIds_.push_back(leashWinSurfaceNodeId);
1963                 }
1964             }
1965             SetSkipEventOnCastPlusInner(persistentId, true);
1966         }
1967         rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1968         return WMError::WM_OK;
1969     };
1970     return taskScheduler_->PostSyncTask(task, __func__);
1971 }
1972 
RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)1973 WMError SceneSessionManager::RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
1974 {
1975     if (!SessionPermission::IsSystemCalling()) {
1976         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
1977         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1978     }
1979     auto task = [this, &persistentIds] {
1980         for (const auto persistentId : persistentIds) {
1981             auto session = GetSceneSession(persistentId);
1982             if (!session || SessionHelper::IsSubWindow(session->GetWindowType())) {
1983                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] not found or is sub window", persistentId);
1984                 continue;
1985             }
1986             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "[win: %{public}d] remove from virtual screen black list", persistentId);
1987             auto surfaceNode = session->GetSurfaceNode();
1988             if (surfaceNode) {
1989                 auto surfaceNodeId = surfaceNode->GetId();
1990                 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1991                 if (iter != skipSurfaceNodeIds_.end()) {
1992                     skipSurfaceNodeIds_.erase(iter);
1993                 }
1994             }
1995             auto leashWinSurfaceNode = session->GetLeashWinSurfaceNode();
1996             if (leashWinSurfaceNode) {
1997                 auto leashWinSurfaceNodeId = leashWinSurfaceNode->GetId();
1998                 auto iter = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), leashWinSurfaceNodeId);
1999                 if (iter != skipSurfaceNodeIds_.end()) {
2000                     skipSurfaceNodeIds_.erase(iter);
2001                 }
2002             }
2003             SetSkipEventOnCastPlusInner(persistentId, false);
2004         }
2005         rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
2006         return WMError::WM_OK;
2007     };
2008     return taskScheduler_->PostSyncTask(task, __func__);
2009 }
2010 
SetScreenPrivacyWindowTagSwitch(uint64_t screenId,const std::vector<std::string> & privacyWindowTags,bool enable)2011 WMError SceneSessionManager::SetScreenPrivacyWindowTagSwitch(
2012     uint64_t screenId, const std::vector<std::string>& privacyWindowTags, bool enable)
2013 {
2014     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "screenId: %{public}" PRIu64 ", tagsize: %{public}zu, enable: %{public}d",
2015         screenId, privacyWindowTags.size(), enable);
2016     if (!SessionPermission::IsSACalling()) {
2017         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
2018         return WMError::WM_ERROR_INVALID_PERMISSION;
2019     }
2020     if (enable) {
2021         for (const auto& privacyWindowTag : privacyWindowTags) {
2022             screenRSBlackListConfigMap_[screenId].insert({ .privacyWindowTag = privacyWindowTag });
2023         }
2024         FlushSessionBlackListInfoMapWhenAdd(screenId);
2025     } else {
2026         for (const auto& privacyWindowTag : privacyWindowTags) {
2027             screenRSBlackListConfigMap_[screenId].erase({ .privacyWindowTag = privacyWindowTag });
2028             if (screenRSBlackListConfigMap_[screenId].empty()) {
2029                 screenRSBlackListConfigMap_.erase(screenId);
2030                 break;
2031             }
2032         }
2033         FlushSessionBlackListInfoMapWhenRemove(screenId);
2034     }
2035     return WMError::WM_OK;
2036 }
2037 
SetSkipEventOnCastPlusInner(int32_t windowId,bool isSkip)2038 void SceneSessionManager::SetSkipEventOnCastPlusInner(int32_t windowId, bool isSkip)
2039 {
2040     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Wid: %{public}d, isSkip: %{public}d", windowId, isSkip);
2041     auto sceneSession = GetSceneSession(windowId);
2042     if(sceneSession == nullptr) {
2043         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "SceneSession is nullptr, Wid: %{public}d", windowId);
2044         return;
2045     }
2046     sceneSession->GetSessionProperty()->SetSkipEventOnCastPlus(isSkip);
2047     FlushWindowInfoToMMI(true);
2048 }
2049 
CreateKeyboardSessionCallback()2050 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
2051 {
2052     auto keyboardCb = sptr<KeyboardSession::KeyboardSessionCallback>::MakeSptr();
2053     keyboardCb->onGetSceneSession = [this](int32_t persistentId) {
2054         return this->GetSceneSession(persistentId);
2055     };
2056     keyboardCb->onGetFocusedSessionId = [this] {
2057         return this->GetFocusedSessionId();
2058     };
2059     keyboardCb->onCallingSessionIdChange = callingSessionIdChangeFunc_;
2060     keyboardCb->onSystemKeyboardAvoidChange = [this](DisplayId displayId, SystemKeyboardAvoidChangeReason reason) {
2061         this->HandleKeyboardAvoidChange(nullptr, displayId, reason);
2062     };
2063     keyboardCb->onNotifyOccupiedAreaChange = [this](const sptr<OccupiedAreaChangeInfo>& info) {
2064         this->onNotifyAvoidAreaChangeForRootFunc_(nullptr, AvoidAreaType::TYPE_KEYBOARD, info);
2065     };
2066     keyboardCb->isLastFrameLayoutFinished = [this]() {
2067         if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
2068             TLOGE(WmsLogTag::WMS_KEYBOARD, "isRootSceneLastFrameLayoutFinishedFunc_ is nullptr");
2069             return true;
2070         }
2071         return isRootSceneLastFrameLayoutFinishedFunc_();
2072     };
2073     return keyboardCb;
2074 }
2075 
CheckWindowId(int32_t windowId,int32_t & pid)2076 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
2077 {
2078     if (!SessionPermission::IsSystemCalling()) {
2079         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
2080         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2081     }
2082 
2083     auto task = [this, windowId, &pid] {
2084         pid = INVALID_PID;
2085         auto sceneSession = GetSceneSession(windowId);
2086         if (sceneSession == nullptr) {
2087             TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession(%{public}d) is nullptr", windowId);
2088             return WMError::WM_ERROR_INVALID_WINDOW;
2089         }
2090         pid = sceneSession->GetCallingPid();
2091         TLOGND(WmsLogTag::WMS_EVENT, "Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
2092         return WMError::WM_OK;
2093     };
2094     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
2095 }
2096 
GetWindowLimits(int32_t windowId,WindowLimits & windowLimits)2097 WMError SceneSessionManager::GetWindowLimits(int32_t windowId, WindowLimits& windowLimits)
2098 {
2099     if (!(systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode())) {
2100         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "not pc device, return.");
2101         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
2102     }
2103     if (!SessionPermission::IsSystemCalling()) {
2104         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "permission denied!");
2105         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2106     }
2107     auto sceneSession = GetSceneSession(windowId);
2108     if (!sceneSession) {
2109         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sceneSession(%{public}d) is nullptr", windowId);
2110         return WMError::WM_ERROR_INVALID_WINDOW;
2111     }
2112     auto sessionProperty = sceneSession->GetSessionProperty();
2113     if (!sessionProperty) {
2114         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "sessionProperty(%{public}d) is nullptr", windowId);
2115         return WMError::WM_ERROR_INVALID_WINDOW;
2116     }
2117     windowLimits = sessionProperty->GetWindowLimits();
2118     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "GetWindowLimits minWidth:%{public}u, minHeight:%{public}u, "
2119         "maxWidth:%{public}u, maxHeight:%{public}u, vpRatio:%{public}f", windowLimits.minWidth_,
2120         windowLimits.minHeight_, windowLimits.maxWidth_, windowLimits.maxHeight_, windowLimits.vpRatio_);
2121     return WMError::WM_OK;
2122 }
2123 
GetLockScreenZOrder()2124 uint32_t SceneSessionManager::GetLockScreenZOrder()
2125 {
2126     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2127     for (const auto& [persistentId, session] : sceneSessionMap_) {
2128         if (session && session->IsScreenLockWindow()) {
2129             TLOGI(WmsLogTag::WMS_UIEXT, "window %{public}d-%{public}d", persistentId,
2130                 session->GetZOrder());
2131             return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
2132                 session->GetZOrder();
2133         }
2134     }
2135     TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
2136     return DEFAULT_LOCK_SCREEN_ZORDER;
2137 }
2138 
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)2139 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
2140     const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
2141 {
2142     if (!SessionPermission::IsSystemCalling()) {
2143         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
2144         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2145     }
2146     auto task = [this, windowId, callingTokenId, &element, extensionAbilityType, &pid] {
2147         pid = INVALID_PID;
2148         auto sceneSession = GetSceneSession(windowId);
2149         if (sceneSession == nullptr) {
2150             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
2151             return WMError::WM_ERROR_INVALID_WINDOW;
2152         }
2153         pid = sceneSession->GetCallingPid();
2154         if (!IsScreenLocked()) {
2155             TLOGND(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
2156             return WMError::WM_OK;
2157         }
2158         if (IsUserAuthPassed()) {
2159             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
2160             return WMError::WM_OK;
2161         }
2162         // 1. check window whether can show on main window
2163         if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
2164             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
2165             return WMError::WM_OK;
2166         }
2167         // 2. check permission
2168         if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
2169             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
2170                 callingTokenId);
2171             return WMError::WM_ERROR_INVALID_PERMISSION;
2172         }
2173         TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: pass");
2174         return WMError::WM_OK;
2175     };
2176 
2177     std::ostringstream ss;
2178     ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
2179     return taskScheduler_->PostSyncTask(task, ss.str());
2180 }
2181 
2182 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)2183 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
2184 {
2185     taskScheduler_->PostSyncTask([this, &windowIds] {
2186         // check every window
2187         for (auto windowId : windowIds) {
2188             auto sceneSession = GetSceneSession(windowId);
2189             if (!sceneSession) {
2190                 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
2191                 continue;
2192             }
2193             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
2194             sceneSession->OnNotifyAboveLockScreen();
2195         }
2196         return WMError::WM_OK;
2197     }, __func__);
2198 }
2199 
GetKeyboardSession(DisplayId displayId,bool isSystemKeyboard)2200 sptr<SceneSession> SceneSessionManager::GetKeyboardSession(DisplayId displayId, bool isSystemKeyboard)
2201 {
2202     if (displayId == DISPLAY_ID_INVALID) {
2203         TLOGE(WmsLogTag::WMS_KEYBOARD, "displayId is invalid.");
2204         return nullptr;
2205     }
2206     sptr<SceneSession> keyboardSession = nullptr;
2207     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2208     for (const auto& [_, sceneSession] : sceneSessionMap_) {
2209         if (sceneSession && sceneSession->GetScreenId() == displayId &&
2210             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
2211             sceneSession->IsSystemKeyboard() == isSystemKeyboard) {
2212             keyboardSession = sceneSession;
2213             break;
2214         }
2215     }
2216     return keyboardSession;
2217 }
2218 
HandleKeyboardAvoidChange(const sptr<SceneSession> & sceneSession,DisplayId displayId,SystemKeyboardAvoidChangeReason reason)2219 void SceneSessionManager::HandleKeyboardAvoidChange(const sptr<SceneSession>& sceneSession, DisplayId displayId,
2220     SystemKeyboardAvoidChangeReason reason)
2221 {
2222     if (!systemConfig_.IsPcWindow()) {
2223         TLOGI(WmsLogTag::WMS_KEYBOARD, "this device is not pc.");
2224         return;
2225     }
2226     switch (reason) {
2227         // if the system keyboard's avoid area is active first, deactivate the other keyboard's avoid area
2228         case SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED: {
2229             if (!sceneSession || sceneSession->IsSystemKeyboard()) {
2230                 return;
2231             }
2232             sptr<SceneSession> systemKeyboardSession = GetKeyboardSession(displayId, true);
2233             if (systemKeyboardSession && systemKeyboardSession->IsSessionForeground() &&
2234                 systemKeyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
2235                 sceneSession->ActivateKeyboardAvoidArea(false, false);
2236             }
2237             break;
2238         }
2239         /*
2240          * activate the system keyboard's avoid area, while it is showing or it's gravity is bottom
2241          * and deactivate other keyboard's avoid area
2242          */
2243         case SystemKeyboardAvoidChangeReason::KEYBOARD_SHOW:
2244         case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_BOTTOM: {
2245             UpdateKeyboardAvoidAreaActive(true);
2246             break;
2247         }
2248         /*
2249          * when the system keyboard is hiden, disconnect or it's gravity is float
2250          * check for whether other keyboard can be avoided: if yes, avoids the other keyboard
2251          *                                                  if no, restores the system keyboard
2252          */
2253         case SystemKeyboardAvoidChangeReason::KEYBOARD_HIDE:
2254         case SystemKeyboardAvoidChangeReason::KEYBOARD_DISCONNECT:
2255         case SystemKeyboardAvoidChangeReason::KEYBOARD_GRAVITY_FLOAT: {
2256             bool keyboardRecalculate = false;
2257             if (auto keyboardSession = GetKeyboardSession(displayId, false)) {
2258                 if (keyboardSession->IsSessionForeground() &&
2259                     keyboardSession->GetKeyboardGravity() == SessionGravity::SESSION_GRAVITY_BOTTOM) {
2260                     keyboardRecalculate = true;
2261                 }
2262                 keyboardSession->ActivateKeyboardAvoidArea(true, keyboardRecalculate);
2263             }
2264             if (auto sysKeyboardSession = GetKeyboardSession(displayId, true)) {
2265                 sysKeyboardSession->ActivateKeyboardAvoidArea(false, !keyboardRecalculate);
2266             }
2267             break;
2268         }
2269         default:
2270             break;
2271     }
2272 }
2273 
UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)2274 void SceneSessionManager::UpdateKeyboardAvoidAreaActive(bool systemKeyboardAvoidAreaActive)
2275 {
2276     const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
2277     if (keyboardSessionVec.empty()) {
2278         TLOGI(WmsLogTag::WMS_KEYBOARD, "there is no keyboard window in the map");
2279         return;
2280     }
2281     for (const auto& keyboardSession : keyboardSessionVec) {
2282         if (!keyboardSession) {
2283             continue;
2284         }
2285         if (keyboardSession->IsSystemKeyboard()) {
2286             keyboardSession->ActivateKeyboardAvoidArea(systemKeyboardAvoidAreaActive, false);
2287         } else {
2288             keyboardSession->ActivateKeyboardAvoidArea(!systemKeyboardAvoidAreaActive, false);
2289         }
2290     }
2291 }
2292 
RequestKeyboardPanelSession(const std::string & panelName,uint64_t displayId)2293 sptr<SceneSession> SceneSessionManager::RequestKeyboardPanelSession(const std::string& panelName, uint64_t displayId)
2294 {
2295     SessionInfo panelInfo = {
2296         .bundleName_ = panelName,
2297         .moduleName_ = panelName,
2298         .abilityName_ = panelName,
2299         .isSystem_ = true,
2300         .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
2301         .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
2302         .screenId_ = displayId,
2303         .isRotable_ = true,
2304     };
2305     TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
2306     return RequestSceneSession(panelInfo, nullptr);
2307 }
2308 
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)2309 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
2310 {
2311     if (!isKeyboardPanelEnabled_) {
2312         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
2313         return;
2314     }
2315     if (keyboardSession == nullptr) {
2316         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
2317         return;
2318     }
2319     const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
2320     sptr<SceneSession> panelSession;
2321     for (const auto& session : panelVec) {
2322         if (session && session->IsSystemKeyboard() == keyboardSession->IsSystemKeyboard()) {
2323             panelSession = session;
2324             break;
2325         }
2326     }
2327     /*
2328      * Only 2 scenarios of panelSession is nullptr:
2329      * 1: neither keyboard panel session nor system keyboard panel session is created.
2330      * 2: a panel session has been created already, but it's isSystemKeyboard is not match with the keyboardSesion's
2331      */
2332     if (panelSession == nullptr) {
2333         if (panelVec.size() >= 2) { // 2 is max number of keyboard panel, one input method and one system keyboard
2334             TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
2335             ReportKeyboardCreateException(keyboardSession);
2336             return;
2337         }
2338         std::string panelName = keyboardSession->IsSystemKeyboard() ? "SCBSystemKeyboardPanel" : "SCBKeyboardPanel";
2339         panelSession = RequestKeyboardPanelSession(panelName,
2340             static_cast<uint64_t>(keyboardSession->GetSessionProperty()->GetDisplayId()));
2341         if (panelSession == nullptr) {
2342             TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
2343             return;
2344         }
2345     } else {
2346         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId: %{public}d",
2347             panelSession->GetPersistentId());
2348     }
2349     panelSession->SetIsSystemKeyboard(keyboardSession->IsSystemKeyboard());
2350     keyboardSession->BindKeyboardPanelSession(panelSession);
2351     panelSession->BindKeyboardSession(keyboardSession);
2352     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
2353         panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
2354 }
2355 
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2356 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
2357     sptr<WindowSessionProperty> property)
2358 {
2359     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
2360     sptr<SceneSession> sceneSession = nullptr;
2361     if (sessionInfo.isSystem_) {
2362         sceneSession = new SCBSystemSession(sessionInfo, specificCb);
2363         TLOGI(WmsLogTag::DEFAULT, "[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
2364     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2365         sceneSession = new MainSession(sessionInfo, specificCb);
2366         TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
2367     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
2368         sceneSession = new SubSession(sessionInfo, specificCb);
2369         TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
2370     } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2371         sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
2372         sceneSession = new KeyboardSession(sessionInfo, specificCb, keyboardCb);
2373         sceneSession->SetIsSystemKeyboard(property->IsSystemKeyboard());
2374         CreateKeyboardPanelSession(sceneSession);
2375         HandleKeyboardAvoidChange(sceneSession, sceneSession->GetScreenId(),
2376             SystemKeyboardAvoidChangeReason::KEYBOARD_CREATED);
2377         TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
2378     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
2379         sceneSession = new SystemSession(sessionInfo, specificCb);
2380         TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
2381     } else {
2382         TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
2383     }
2384     if (sceneSession != nullptr) {
2385         sceneSession->SetWindowAnimationDuration(appWindowSceneConfig_.windowAnimation_.duration_);
2386         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
2387         sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
2388         sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
2389             return this->GetAppForceLandscapeConfig(bundleName);
2390         });
2391         sceneSession->RegisterAppHookWindowInfoFunc([this](const std::string& bundleName) {
2392             return this->GetAppHookWindowInfo(bundleName);
2393         });
2394         sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
2395             this->UpdatePrivateStateAndNotify(persistentId);
2396         });
2397         sceneSession->SetNotifyScreenshotAppEventRegisteredFunc([this](int32_t persistentId, bool isRegister) {
2398             this->UpdateSessionScreenshotAppEventListener(persistentId, isRegister);
2399         });
2400         sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
2401             this->NotifyVisibleChange(persistentId);
2402         });
2403         sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
2404             return this->IsLastFrameLayoutFinished(isLayoutFinished);
2405         });
2406         sceneSession->SetIsAINavigationBarAvoidAreaValidFunc([this](const AvoidArea& avoidArea, int32_t sessionBottom) {
2407             return CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea, sessionBottom);
2408         });
2409         sceneSession->RegisterGetStatusBarAvoidHeightFunc([this](DisplayId displayId, WSRect& barArea) {
2410             return this->GetStatusBarAvoidHeight(displayId, barArea);
2411         });
2412         sceneSession->RegisterGetStatusBarConstantlyShowFunc([this](DisplayId displayId, bool& isVisible) {
2413             return this->GetStatusBarConstantlyShow(displayId, isVisible);
2414         });
2415         sceneSession->SetHasRequestedVsyncFunc([this](bool& hasRequestedVsync) {
2416             return this->HasRootSceneRequestedVsync(hasRequestedVsync);
2417         });
2418         sceneSession->SetRequestNextVsyncWhenModeChangeFunc(
2419             [this](const std::shared_ptr<VsyncCallback>& vsyncCallback) {
2420             return this->RequestVsyncByRootSceneWhenModeChange(vsyncCallback);
2421         });
2422         sceneSession->SetGetAllAppUseControlMapFunc([this]() ->
2423             std::unordered_map<std::string, std::unordered_map<ControlAppType, ControlInfo>>& {
2424             return allAppUseControlMap_;
2425         });
2426         sceneSession->RegisterGetFbPanelWindowIdFunc([this](uint32_t& windowId) {
2427             return this->GetFbPanelWindowId(windowId);
2428         });
2429         DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2430         GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
2431         sceneSession->SetAppDragResizeType(dragResizeType);
2432         sceneSession->SetKeyFramePolicy(GetAppKeyFramePolicy(sessionInfo.bundleName_));
2433         sceneSession->SetSingleHandTransform(singleHandTransform_);
2434         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
2435             sceneSession->GetPersistentId(), sceneSession->GetSessionProperty()->GetDisplayId());
2436     }
2437     return sceneSession;
2438 }
2439 
GetEffectiveDragResizeType(DragResizeType & dragResizeType)2440 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
2441 {
2442     if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2443         return;
2444     }
2445     if (systemConfig_.freeMultiWindowSupport_) {
2446         if (systemConfig_.freeMultiWindowConfig_.defaultDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2447             dragResizeType = systemConfig_.freeMultiWindowConfig_.defaultDragResizeType_;
2448             return;
2449         }
2450         dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
2451     } else {
2452         dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
2453     }
2454 }
2455 
SetGlobalDragResizeType(DragResizeType dragResizeType)2456 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
2457 {
2458     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2459     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2460         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2461         return WMError::WM_ERROR_INVALID_PERMISSION;
2462     }
2463     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2464     globalDragResizeType_ = dragResizeType;
2465     taskScheduler_->PostAsyncTask([this] {
2466         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2467         for (const auto& [_, sceneSession] : sceneSessionMap_) {
2468             if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2469                 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
2470                 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2471                 GetAppDragResizeType(bundleName, appDragResizeType);
2472                 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2473                     "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
2474                 sceneSession->SetAppDragResizeType(appDragResizeType);
2475             }
2476         }
2477     }, __func__);
2478     return WMError::WM_OK;
2479 }
2480 
GetGlobalDragResizeType(DragResizeType & dragResizeType)2481 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
2482 {
2483     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2484     dragResizeType = globalDragResizeType_;
2485     GetEffectiveDragResizeType(dragResizeType);
2486     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
2487     return WMError::WM_OK;
2488 }
2489 
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)2490 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
2491 {
2492     TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2493         dragResizeType, bundleName.c_str());
2494     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2495         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2496         return WMError::WM_ERROR_INVALID_PERMISSION;
2497     }
2498     return SetAppDragResizeTypeInner(bundleName, dragResizeType);
2499 }
2500 
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)2501 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
2502 {
2503     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2504         dragResizeType, bundleName.c_str());
2505     if (bundleName.empty()) {
2506         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2507         return WMError::WM_ERROR_INVALID_PARAM;
2508     }
2509     std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
2510     appDragResizeTypeMap_[bundleName] = dragResizeType;
2511     GetAppDragResizeTypeInner(bundleName, dragResizeType);
2512     taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
2513         auto allMatchSession = GetSceneSessionByBundleName(bundleName);
2514         for (const auto& sceneSession : allMatchSession) {
2515             if (sceneSession != nullptr) {
2516                 TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
2517                     "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
2518                 sceneSession->SetAppDragResizeType(dragResizeType);
2519             }
2520         }
2521     }, __func__);
2522     return WMError::WM_OK;
2523 }
2524 
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)2525 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
2526 {
2527     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
2528     return GetAppDragResizeTypeInner(bundleName, dragResizeType);
2529 }
2530 
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)2531 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
2532 {
2533     if (bundleName.empty()) {
2534         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2535         return WMError::WM_ERROR_INVALID_PARAM;
2536     }
2537     if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
2538         TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
2539         dragResizeType = globalDragResizeType_;
2540         return WMError::WM_OK;
2541     }
2542     dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
2543     if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
2544         dragResizeType = iter->second;
2545     }
2546     GetEffectiveDragResizeType(dragResizeType);
2547     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
2548         dragResizeType, bundleName.c_str());
2549     return WMError::WM_OK;
2550 }
2551 
SetAppKeyFramePolicy(const std::string & bundleName,const KeyFramePolicy & keyFramePolicy)2552 WMError SceneSessionManager::SetAppKeyFramePolicy(const std::string& bundleName,
2553     const KeyFramePolicy& keyFramePolicy)
2554 {
2555     TLOGI(WmsLogTag::WMS_LAYOUT, "keyFramePolicy enabled: %{public}d, bundleName: %{public}s",
2556         keyFramePolicy.enabled(), bundleName.c_str());
2557     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
2558         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
2559         return WMError::WM_ERROR_INVALID_PERMISSION;
2560     }
2561     if (bundleName.empty()) {
2562         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
2563         return WMError::WM_ERROR_INVALID_PARAM;
2564     }
2565     {
2566         std::lock_guard<std::mutex> lock(keyFrameMutex_);
2567         appKeyFramePolicyMap_[bundleName] = keyFramePolicy;
2568     }
2569     taskScheduler_->PostAsyncTask([this, bundleName, keyFramePolicy, where = __func__] {
2570         auto allMatchSession = GetSceneSessionByBundleName(bundleName);
2571         for (const auto& sceneSession : allMatchSession) {
2572             if (sceneSession != nullptr && systemConfig_.IsPcWindow() &&
2573                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2574                 TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: pc main window id: %{public}d, bundleName: %{public}s",
2575                     where, sceneSession->GetPersistentId(), bundleName.c_str());
2576                 sceneSession->SetKeyFramePolicy(keyFramePolicy);
2577             }
2578         }
2579     }, __func__);
2580     return WMError::WM_OK;
2581 }
2582 
GetAppKeyFramePolicy(const std::string & bundleName)2583 KeyFramePolicy SceneSessionManager::GetAppKeyFramePolicy(const std::string& bundleName)
2584 {
2585     {
2586         std::lock_guard<std::mutex> lock(keyFrameMutex_);
2587         if (auto iter = appKeyFramePolicyMap_.find(bundleName); iter != appKeyFramePolicyMap_.end()) {
2588             return iter->second;
2589         }
2590     }
2591     return KeyFramePolicy();
2592 }
2593 
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)2594 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
2595 {
2596     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
2597         if (auto session = GetSceneSession(sessionInfo.persistentId_)) {
2598             TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
2599             return session;
2600         }
2601 
2602         if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
2603             TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
2604                 "abilityName: %{public}s, appIndex: %{public}d",
2605                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2606                 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
2607             SessionIdentityInfo identityInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_,
2608                 sessionInfo.abilityName_, sessionInfo.appIndex_, sessionInfo.appInstanceKey_, sessionInfo.windowType_,
2609                 sessionInfo.isAtomicService_ };
2610             auto sceneSession = GetSceneSessionByIdentityInfo(identityInfo);
2611             bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
2612                 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
2613             if (isSingleStart) {
2614                 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
2615                     sessionInfo.persistentId_);
2616                 return sceneSession;
2617             }
2618         }
2619     }
2620     return nullptr;
2621 }
2622 
GetHookedSessionByModuleName(const SessionInfo & sessionInfo)2623 sptr<SceneSession> SceneSessionManager::GetHookedSessionByModuleName(const SessionInfo& sessionInfo)
2624 {
2625     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2626     sptr<SceneSession> session = nullptr;
2627     for (const auto &[_, sceneSession] : sceneSessionMap_) {
2628         if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
2629             continue;
2630         }
2631         if (sceneSession->GetSessionInfo().bundleName_ != sessionInfo.bundleName_ ||
2632             sceneSession->GetSessionInfo().moduleName_ != sessionInfo.moduleName_ ||
2633             sceneSession->GetSessionInfo().appIndex_ != sessionInfo.appIndex_ ||
2634             sceneSession->GetSessionInfo().appInstanceKey_ != sessionInfo.appInstanceKey_) {
2635             continue;
2636         }
2637         if (sceneSession->GetSessionInfo().disableDelegator) {
2638             return nullptr;
2639         } else {
2640             session = sceneSession;
2641         }
2642     }
2643     return session;
2644 }
2645 
UpdateAbilityHookState(sptr<SceneSession> & sceneSession,bool isAbilityHook)2646 void SceneSessionManager::UpdateAbilityHookState(sptr<SceneSession>& sceneSession, bool isAbilityHook)
2647 {
2648     if (!sceneSession || !isAbilityHook)  {
2649         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null or isAbilityHook is false");
2650         return;
2651     }
2652     sceneSession->EditSessionInfo().isAbilityHook_ = isAbilityHook;
2653     RegisterHookSceneSessionActivationFunc(sceneSession);
2654 }
2655 
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)2656 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
2657     sptr<WindowSessionProperty> property)
2658 {
2659     auto task = [this, sessionInfo, property, where = __func__] {
2660         if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
2661             UpdateSessionDisplayIdBySessionInfo(session, sessionInfo);
2662             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2663             UpdateAbilityHookState(session, sessionInfo.isAbilityHook_);
2664             return session;
2665         }
2666         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
2667             "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
2668             where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
2669             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
2670             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
2671         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
2672         if (sceneSession == nullptr) {
2673             TLOGNE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
2674             return sceneSession;
2675         }
2676         if (sessionInfo.isAbilityHook_) {
2677             auto session = GetHookedSessionByModuleName(sessionInfo);
2678             if (session) {
2679                 TLOGNW(WmsLogTag::WMS_LIFE, "session disableDelegator %{public}d is still hook, return hook session",
2680                     session->GetSessionInfo().disableDelegator);
2681                 return session;
2682             }
2683             RegisterHookSceneSessionActivationFunc(sceneSession);
2684         }
2685         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2686             WindowHelper::IsMainWindow(sceneSession->GetWindowType()) &&
2687             MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2688             MultiInstanceManager::GetInstance().FillInstanceKeyIfNeed(sceneSession);
2689         }
2690         LOCK_GUARD_EXPR(SCENE_GUARD, InitSceneSession(sceneSession, sessionInfo, property));
2691         PreLoadStartingWindow(sceneSession);
2692         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2693             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
2694                 where, sceneSession->GetSessionInfo().ancoSceneState);
2695             bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
2696             const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
2697             if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
2698                 TLOGNI(WmsLogTag::WMS_LIFE,
2699                     "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
2700                     where, reusedSceneSession->GetPersistentId(),
2701                     reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
2702                 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
2703                 return reusedSceneSession;
2704             }
2705             if (isPreHandleSuccess) {
2706                 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
2707                 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
2708             }
2709         }
2710         {
2711             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2712             sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
2713             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2714                 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2715                 MultiInstanceManager::GetInstance().IncreaseInstanceKeyRefCount(sceneSession);
2716             }
2717         }
2718         PerformRegisterInRequestSceneSession(sceneSession);
2719         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
2720         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: id: %{public}d, type: %{public}d, instanceKey: %{public}s, "
2721                "displayId: %{public}" PRIu64, where, sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
2722                sceneSession->GetAppInstanceKey().c_str(), sceneSession->GetSessionProperty()->GetDisplayId());
2723         return sceneSession;
2724     };
2725     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
2726 }
2727 
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)2728 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
2729     const sptr<WindowSessionProperty>& property)
2730 {
2731     auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
2732     DisplayId currDisplayId = DISPLAY_ID_INVALID;
2733     if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
2734         currDisplayId = sessionInfo.screenId_;
2735     } else if (callerSession) {
2736         currDisplayId = callerSession->GetSessionProperty()->GetDisplayId();
2737     }
2738     sceneSession->GetSessionProperty()->SetDisplayId(currDisplayId);
2739     sceneSession->SetScreenId(currDisplayId);
2740     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "synchronous screenId with displayId %{public}" PRIu64, currDisplayId);
2741 
2742     sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
2743     sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
2744     if (sessionInfo.isSystem_) {
2745         sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
2746         sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
2747         auto rootContext = rootSceneContextWeak_.lock();
2748         sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
2749     } else {
2750         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
2751             "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
2752             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2753             sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
2754     }
2755     RegisterSessionExceptionFunc(sceneSession);
2756     RegisterVisibilityChangedDetectFunc(sceneSession);
2757     RegisterSaveSnapshotFunc(sceneSession);
2758     if (systemConfig_.IsPcOrPcMode()) {
2759         RegisterGetStartWindowConfigCallback(sceneSession);
2760     }
2761     if (systemConfig_.windowUIType_ == WindowUIType::PAD_WINDOW) {
2762         RegisterRemoveSnapshotFunc(sceneSession);
2763     }
2764     // Skip FillSessionInfo when atomicService free-install start.
2765     if (!IsAtomicServiceFreeInstall(sessionInfo)) {
2766         FillSessionInfo(sceneSession);
2767     }
2768     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
2769     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
2770         WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
2771     }
2772     if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
2773         sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
2774     }
2775     InitFbWindow(sceneSession, property);
2776     auto systemConfig = systemConfig_;
2777     SetWindowStatusDeduplicationBySystemConfig(sessionInfo, systemConfig);
2778     sceneSession->SetSystemConfig(systemConfig);
2779     sceneSession->InitSnapshotCapacity();
2780     sceneSession->SetSnapshotScale(snapshotScale_);
2781     UpdateParentSessionForDialog(sceneSession, property);
2782     std::string key = sessionInfo.bundleName_ + "_" + sessionInfo.moduleName_ + "_" + sessionInfo.abilityName_ + "_" +
2783         std::to_string(sessionInfo.appIndex_);
2784     if (sessionLockedStateCacheSet_.find(key) != sessionLockedStateCacheSet_.end()) {
2785         sceneSession->NotifySessionLockStateChange(true);
2786     }
2787 }
2788 
InitFbWindow(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)2789 void SceneSessionManager::InitFbWindow(const sptr<SceneSession>& sceneSession,
2790     const sptr<WindowSessionProperty>& property)
2791 {
2792     if (property != nullptr && WindowHelper::IsFbWindow(property->GetWindowType())) {
2793         sceneSession->SetFbTemplateInfo(property->GetFbTemplateInfo());
2794     }
2795 }
2796 
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)2797 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
2798 {
2799     taskScheduler_->PostAsyncTask([abilityName = sessionInfo.abilityName_,
2800         bundleName = sessionInfo.bundleName_, toScreenId = sessionInfo.screenId_, action, fromScreenId] {
2801         sptr<DisplayChangeInfo> info = sptr<DisplayChangeInfo>::MakeSptr();
2802         info->action_ = action;
2803         info->abilityName_ = std::move(abilityName);
2804         info->bundleName_ = std::move(bundleName);
2805         info->toScreenId_ = toScreenId;
2806         info->fromScreenId_ = fromScreenId;
2807         ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
2808         TLOGNI(WmsLogTag::DMS, "Notify ability %{public}s bundle %{public}s update toScreen id: %{public}" PRIu64,
2809             info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
2810     }, __func__);
2811 }
2812 
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)2813 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
2814 {
2815     RegisterSessionSnapshotFunc(sceneSession);
2816     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
2817     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
2818     RegisterDisplayIdChangedNotifyManagerFunc(sceneSession);
2819     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
2820     RegisterGetStateFromManagerFunc(sceneSession);
2821     RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
2822     RegisterAcquireRotateAnimationConfigFunc(sceneSession);
2823     RegisterRequestVsyncFunc(sceneSession);
2824     RegisterSceneSessionDestructNotifyManagerFunc(sceneSession);
2825     RegisterSessionPropertyChangeNotifyManagerFunc(sceneSession);
2826 }
2827 
UpdateSceneSessionWant(const SessionInfo & sessionInfo)2828 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
2829 {
2830     if (sessionInfo.persistentId_ != 0) {
2831         auto session = GetSceneSession(sessionInfo.persistentId_);
2832         if (session != nullptr && sessionInfo.want != nullptr) {
2833             TLOGI(WmsLogTag::WMS_MAIN, "Get session id:%{public}d", sessionInfo.persistentId_);
2834             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
2835                 session->SetSessionInfoWant(sessionInfo.want);
2836                 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
2837             } else {
2838                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
2839             }
2840         } else {
2841             TLOGI(WmsLogTag::WMS_MAIN, "Get session fail(%{public}d), id:%{public}d",
2842                 session == nullptr, sessionInfo.persistentId_);
2843         }
2844     } else {
2845         TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
2846     }
2847 }
2848 
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2849 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2850 {
2851     if (session != nullptr && session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2852         FillSessionInfo(session);
2853         if (CheckCollaboratorType(session->GetCollaboratorType())) {
2854             PreHandleCollaborator(session, persistentId);
2855         }
2856     }
2857 }
2858 
SetAbilitySessionInfo(const sptr<SceneSession> & sceneSession,int32_t requestId)2859 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& sceneSession,
2860     int32_t requestId)
2861 {
2862     const auto& sessionInfo = sceneSession->GetSessionInfo();
2863     auto abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
2864     abilitySessionInfo->sessionToken = sptr<ISession>(sceneSession)->AsObject();
2865     abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2866         std::chrono::system_clock::now()).time_since_epoch().count());
2867     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2868     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2869         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2870     abilitySessionInfo->persistentId = sceneSession->GetPersistentId();
2871     abilitySessionInfo->requestCode = sessionInfo.requestCode;
2872     abilitySessionInfo->resultCode = sessionInfo.resultCode;
2873     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2874     abilitySessionInfo->startSetting = sessionInfo.startSetting;
2875     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2876     abilitySessionInfo->userId = currentUserId_;
2877     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2878     abilitySessionInfo->processOptions = sessionInfo.processOptions;
2879     abilitySessionInfo->requestId = sessionInfo.requestId;
2880     abilitySessionInfo->reuseDelegatorWindow = sessionInfo.reuseDelegatorWindow;
2881     abilitySessionInfo->specifiedFlag = sessionInfo.specifiedFlag_;
2882     if (sessionInfo.want != nullptr) {
2883         abilitySessionInfo->want = sessionInfo.GetWantSafely();
2884     } else {
2885         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2886             sessionInfo.moduleName_);
2887     }
2888     int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2889     bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2890     if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2891         TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2892             appIndex, sessionInfo.appIndex_);
2893     }
2894     if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2895         TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2896         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2897     }
2898     abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2899         static_cast<int>(sceneSession->GetSessionProperty()->GetDisplayId()));
2900     abilitySessionInfo->instanceKey = sessionInfo.appInstanceKey_;
2901     if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2902         sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2903         abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2904     } else {
2905         TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2906     }
2907     abilitySessionInfo->scenarios = sessionInfo.scenarios;
2908     TLOGI(WmsLogTag::WMS_LIFE, "Is SCB Call, set flag:%{public}d, persistentId:%{public}d, requestId:%{public}d",
2909         requestId == DEFAULT_REQUEST_FROM_SCB_ID, abilitySessionInfo->persistentId, requestId);
2910     return abilitySessionInfo;
2911 }
2912 
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2913 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2914 {
2915     if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2916         isPrepareTerminate = false;
2917         TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2918         return WSError::WS_OK;
2919     }
2920     auto sceneSession = GetSceneSession(persistentId);
2921     if (sceneSession == nullptr) {
2922         TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2923         isPrepareTerminate = false;
2924         return WSError::WS_ERROR_NULLPTR;
2925     }
2926     auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2927     auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2928         PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2929     TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2930         "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2931     return WSError::WS_OK;
2932 }
2933 
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive,int32_t requestId)2934 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive,
2935     int32_t requestId)
2936 {
2937     auto task = [this, weakSceneSession = wptr(sceneSession), isNewActive,
2938         requestId]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
2939         OHOS::HiviewDFX::HiTraceId hiTraceId = OHOS::HiviewDFX::HiTraceChain::GetId();
2940         bool isValid = hiTraceId.IsValid();
2941         if (!isValid) {
2942             hiTraceId = OHOS::HiviewDFX::HiTraceChain::Begin("WindowCreateOnCall",
2943                 HiTraceFlag::HITRACE_FLAG_INCLUDE_ASYNC | HiTraceFlag::HITRACE_FLAG_NO_BE_INFO |
2944                 HiTraceFlag::HITRACE_FLAG_DONOT_CREATE_SPAN);
2945         }
2946         sptr<SceneSession> sceneSession = weakSceneSession.promote();
2947         if (sceneSession == nullptr) {
2948             TLOGNE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2949             if (!isValid) {
2950                 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
2951             }
2952             return WSError::WS_ERROR_NULLPTR;
2953         }
2954         if (!Session::IsScbCoreEnabled()) {
2955             sceneSession->SetForegroundInteractiveStatus(true);
2956         }
2957         auto persistentId = sceneSession->GetPersistentId();
2958         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2959         TLOGNI(WmsLogTag::WMS_MAIN,
2960             "Request active id:%{public}d, system:%{public}d, isNewActive:%{public}d, requestId:%{public}d",
2961             persistentId, sceneSession->GetSessionInfo().isSystem_,
2962             isNewActive, sceneSession->GetSessionInfo().requestId);
2963         if (!GetSceneSession(persistentId)) {
2964             TLOGNE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2965             if (!isValid) {
2966                 OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
2967             }
2968             return WSError::WS_ERROR_INVALID_SESSION;
2969         }
2970         auto ret = RequestSceneSessionActivationInner(sceneSession, isNewActive, requestId);
2971         if (ret == WSError::WS_OK) {
2972             sceneSession->SetExitSplitOnBackground(false);
2973         }
2974         abilityInfoMap_.clear(); // clear cache after terminate
2975         if (!isValid) {
2976             OHOS::HiviewDFX::HiTraceChain::End(hiTraceId);
2977         }
2978         return ret;
2979     };
2980     std::string taskName = "RequestSceneSessionActivation:PID:" +
2981         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2982     taskScheduler_->PostAsyncTask(task, taskName);
2983     return WSError::WS_OK;
2984 }
2985 
NotifyAmsPendingSessionWhenFail(uint32_t resultCode,std::string resultMessage,int32_t requestId)2986 void SceneSessionManager::NotifyAmsPendingSessionWhenFail(uint32_t resultCode, std::string resultMessage,
2987         int32_t requestId)
2988 {
2989     TLOGE(WmsLogTag::WMS_LIFE, "failed, requestId:%{public}d", requestId);
2990     ffrtQueueHelper_->SubmitTask([requestId]{
2991          AAFwk::AbilityManagerClient::GetInstance()->NotifyStartupExceptionBySCB(requestId);
2992     });
2993 }
2994 
IsKeyboardForeground()2995 bool SceneSessionManager::IsKeyboardForeground()
2996 {
2997     bool isKeyboardForeground = false;
2998     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2999     for (const auto& [_, sceneSession] : sceneSessionMap_) {
3000         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3001             isKeyboardForeground = sceneSession->IsSessionForeground();
3002             break;
3003         }
3004     }
3005     return isKeyboardForeground;
3006 }
3007 
RequestInputMethodCloseKeyboard(const int32_t persistentId)3008 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
3009 {
3010     auto sceneSession = GetSceneSession(persistentId);
3011     if (sceneSession == nullptr) {
3012         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
3013         return;
3014     }
3015     // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
3016     if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
3017         !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
3018         TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
3019             persistentId, sceneSession->GetSessionState());
3020         sceneSession->RequestHideKeyboard(true);
3021     }
3022 }
3023 
ResetSceneMissionInfo(const sptr<AAFwk::SessionInfo> & abilitySessionInfo)3024 void SceneSessionManager::ResetSceneMissionInfo(const sptr<AAFwk::SessionInfo>& abilitySessionInfo)
3025 {
3026     abilitySessionInfo->scenarios = 0; // 0 after app started, scenarios reset to initial value
3027 }
3028 
StartUIAbilityBySCBTimeoutCheck(const sptr<SceneSession> & sceneSession,const sptr<AAFwk::SessionInfo> & abilitySessionInfo,const uint32_t & windowStateChangeReason,bool & isColdStart)3029 int32_t SceneSessionManager::StartUIAbilityBySCBTimeoutCheck(const sptr<SceneSession>& sceneSession,
3030     const sptr<AAFwk::SessionInfo>& abilitySessionInfo, const uint32_t& windowStateChangeReason, bool& isColdStart)
3031 {
3032     std::shared_ptr<int32_t> retCode = std::make_shared<int32_t>(0);
3033     std::shared_ptr<bool> coldStartFlag = std::make_shared<bool>(false);
3034     bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([this, sceneSession, abilitySessionInfo,
3035         coldStartFlag, retCode, windowStateChangeReason] {
3036         int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("WMS:SSM:StartUIAbilityBySCB",
3037             START_UI_ABILITY_TIMEOUT/1000, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
3038         auto result = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo,
3039             *coldStartFlag, windowStateChangeReason);
3040         CloseAllFd(sceneSession->GetSessionInfo().want);
3041         HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
3042         *retCode = static_cast<int32_t>(result);
3043         TLOGNI(WmsLogTag::WMS_LIFE, "start ui ability retCode: %{public}d", *retCode);
3044     }, START_UI_ABILITY_TIMEOUT);
3045 
3046     if (isTimeout) {
3047         TLOGE(WmsLogTag::WMS_LIFE, "start ui ability timeout, currentUserId: %{public}d", currentUserId_.load());
3048         return static_cast<int32_t>(WSError::WS_ERROR_START_UI_ABILITY_TIMEOUT);
3049     }
3050     ResetSceneMissionInfo(abilitySessionInfo);
3051     isColdStart = *coldStartFlag;
3052     return *retCode;
3053 }
3054 
CloseAllFd(std::shared_ptr<AAFwk::Want> & want)3055 void SceneSessionManager::CloseAllFd(std::shared_ptr<AAFwk::Want>& want)
3056 {
3057     if (want) {
3058         want->CloseAllFd();
3059     }
3060 }
3061 
StartUIAbilityBySCB(sptr<SceneSession> & sceneSession)3062 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& sceneSession)
3063 {
3064     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3065     return StartUIAbilityBySCB(abilitySessionInfo, sceneSession);
3066 }
3067 
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo,sptr<SceneSession> & sceneSession)3068 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo,
3069     sptr<SceneSession>& sceneSession)
3070 {
3071     bool isColdStart = false;
3072     return StartUIAbilityBySCBTimeoutCheck(sceneSession, abilitySessionInfo,
3073         static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
3074 }
3075 
ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession> & sceneSession,bool visibility,bool isNewWant,bool isFromClient)3076 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(const sptr<SceneSession>& sceneSession,
3077     bool visibility, bool isNewWant, bool isFromClient)
3078 {
3079     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3080     if (!isFromClient) {
3081         sceneSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
3082     }
3083     if(visibility) {
3084         abilitySessionInfo->isNewWant = isNewWant;
3085         TLOGI(WmsLogTag::WMS_MAIN, "ChangUIAbilityVisibility isNewActive:%{public}d, isVisibility: %{public}d",
3086             abilitySessionInfo->isNewWant, visibility);
3087     }
3088     return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
3089 }
3090 
RequestSceneSessionActivationInner(sptr<SceneSession> & sceneSession,bool isNewActive,int32_t requestId)3091 WSError SceneSessionManager::RequestSceneSessionActivationInner(
3092     sptr<SceneSession>& sceneSession, bool isNewActive, int32_t requestId)
3093 {
3094     auto persistentId = sceneSession->GetPersistentId();
3095     RequestInputMethodCloseKeyboard(persistentId);
3096     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3097         sceneSession->SetIsStarting(true);
3098         sceneSession->SetStartingBeforeVisible(true);
3099     }
3100     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) && sceneSession->IsFocusedOnShow()) {
3101         if (Session::IsScbCoreEnabled()) {
3102             if (sceneSession->IsVisibleForeground()) {
3103                 RequestSessionFocusImmediately(persistentId);
3104             } else {
3105                 PostProcessFocusState state = { true, true, true, FocusChangeReason::SCB_START_APP };
3106                 sceneSession->SetPostProcessFocusState(state);
3107             }
3108         } else {
3109             RequestSessionFocusImmediately(persistentId);
3110         }
3111     }
3112     if (sceneSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
3113         FillSessionInfo(sceneSession);
3114         if (CheckCollaboratorType(sceneSession->GetCollaboratorType()) &&
3115             !PreHandleCollaborator(sceneSession, persistentId)) {
3116             TLOGE(WmsLogTag::WMS_LIFE, "[id: %{public}d] ancoSceneState: %{public}d",
3117                 persistentId, sceneSession->GetSessionInfo().ancoSceneState);
3118             ExceptionInfo exceptionInfo;
3119             exceptionInfo.needRemoveSession = true;
3120             sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
3121             NotifyAmsPendingSessionWhenFail(static_cast<uint32_t>(RequestResultCode::FAIL),
3122                 "", sceneSession->GetSessionInfo().requestId);
3123             return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
3124         }
3125     }
3126     sceneSession->NotifyActivation();
3127     auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession, requestId);
3128     sceneSessionInfo->isNewWant = isNewActive;
3129     if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3130         sceneSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, sceneSessionInfo->persistentId);
3131         sceneSessionInfo->collaboratorType = sceneSession->GetCollaboratorType();
3132     }
3133     TLOGI(WmsLogTag::WMS_LIFE, "[id: %{public}d] want-ability: %{public}s, bundle: %{public}s, "
3134         "module: %{public}s, uri: %{public}s, appIndex: %{public}d, requestId:%{public}d", persistentId,
3135         sceneSessionInfo->want.GetElement().GetAbilityName().c_str(),
3136         sceneSessionInfo->want.GetElement().GetBundleName().c_str(),
3137         sceneSessionInfo->want.GetElement().GetModuleName().c_str(),
3138         sceneSessionInfo->want.GetElement().GetURI().c_str(),
3139         sceneSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0),
3140         sceneSessionInfo->requestId);
3141     int32_t errCode = ERR_OK;
3142     bool isColdStart = false;
3143     if (!sceneSession->IsSessionForeground()) {
3144         listenerController_->NotifySessionLifecycleEvent(ISessionLifecycleListener::SessionLifecycleEvent::FOREGROUND,
3145             sceneSession->GetSessionInfo());
3146     }
3147     if (!systemConfig_.backgroundswitch || sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc()) {
3148         TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Begin StartUIAbility, system: %{public}u", persistentId,
3149             static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
3150         errCode = StartUIAbilityBySCBTimeoutCheck(sceneSession, sceneSessionInfo,
3151             static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
3152     } else {
3153         TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Background switch on, isNewActive %{public}d state %{public}u "
3154             "reuseDelegatorWindow %{public}d", persistentId,
3155             isNewActive, sceneSession->GetSessionState(), sceneSession->GetSessionInfo().reuseDelegatorWindow);
3156         if (isNewActive || sceneSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
3157             sceneSession->GetSessionState() == SessionState::STATE_END ||
3158             sceneSession->GetSessionInfo().reuseDelegatorWindow) {
3159             TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
3160                 static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
3161             errCode = StartUIAbilityBySCBTimeoutCheck(sceneSession, sceneSessionInfo,
3162                 static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL), isColdStart);
3163         } else {
3164             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
3165             sceneSession->NotifySessionForeground(1, true);
3166         }
3167     }
3168     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3169         WindowInfoReporter::GetInstance().InsertShowReportInfo(sceneSession->GetSessionInfo().bundleName_);
3170     }
3171     NotifyCollaboratorAfterStart(sceneSession, sceneSessionInfo);
3172     if (errCode != ERR_OK) {
3173         TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
3174         ExceptionInfo exceptionInfo;
3175         exceptionInfo.needRemoveSession = true;
3176         sceneSession->NotifySessionExceptionInner(sceneSessionInfo, exceptionInfo, false, true);
3177         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
3178             startUIAbilityErrorFunc_(
3179                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
3180         }
3181     }
3182     if (isColdStart) {
3183         TLOGI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
3184             sceneSessionInfo->identityToken.c_str(), sceneSession->GetSessionInfo().bundleName_.c_str());
3185         sceneSession->SetClientIdentityToken(sceneSessionInfo->identityToken);
3186         sceneSession->ResetSessionConnectState();
3187         sceneSession->ResetIsActive();
3188         sceneSession->UpdatePrivacyModeControlInfo();
3189     }
3190     return WSError::WS_OK;
3191 }
3192 
NotifyCollaboratorAfterStart(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> & sceneSessionInfo)3193 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& sceneSession,
3194     sptr<AAFwk::SessionInfo>& sceneSessionInfo)
3195 {
3196     if (sceneSession == nullptr || sceneSessionInfo == nullptr) {
3197         return;
3198     }
3199     if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3200         NotifyLoadAbility(sceneSession->GetCollaboratorType(),
3201             sceneSessionInfo, sceneSession->GetSessionInfo().abilityInfo);
3202         NotifyUpdateSessionInfo(sceneSession);
3203         NotifyMoveSessionToForeground(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
3204         sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
3205     }
3206 }
3207 
IsPcSceneSessionLifecycle(const sptr<SceneSession> & sceneSession)3208 bool SceneSessionManager::IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)
3209 {
3210     bool isPcAppInLargeScreenDevice = sceneSession->GetSessionProperty()->GetIsPcAppInPad();
3211     bool isAppSupportPhoneInPc = sceneSession->GetSessionProperty()->GetIsAppSupportPhoneInPc();
3212     return (systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) ||
3213              (isPcAppInLargeScreenDevice && !IsScreenLocked() && !systemConfig_.IsPhoneWindow());
3214 }
3215 
InitSnapshotCache()3216 void SceneSessionManager::InitSnapshotCache()
3217 {
3218     const static std::unordered_map<WindowUIType, std::size_t> SNAPSHOT_CACHE_CAPACITY_MAP = {
3219         {WindowUIType::PC_WINDOW,      MAX_SNAPSHOT_IN_RECENT_PC},
3220         {WindowUIType::PAD_WINDOW,     MAX_SNAPSHOT_IN_RECENT_PAD},
3221         {WindowUIType::PHONE_WINDOW,   MAX_SNAPSHOT_IN_RECENT_PHONE},
3222         {WindowUIType::INVALID_WINDOW, MAX_SNAPSHOT_IN_RECENT_PHONE},
3223     };
3224 
3225     snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(WindowUIType::INVALID_WINDOW);
3226     auto uiType = systemConfig_.windowUIType_;
3227     if (SNAPSHOT_CACHE_CAPACITY_MAP.find(uiType) != SNAPSHOT_CACHE_CAPACITY_MAP.end()) {
3228         snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(uiType);
3229     }
3230     TLOGI(WmsLogTag::WMS_PATTERN, "type: %{public}hhu", uiType);
3231     snapshotLruCache_ = std::make_unique<LruCache>(snapshotCapacity_);
3232 }
3233 
PutSnapshotToCache(int32_t persistentId)3234 void SceneSessionManager::PutSnapshotToCache(int32_t persistentId)
3235 {
3236     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
3237     if (int32_t removedCacheId = snapshotLruCache_->Put(persistentId);
3238         removedCacheId != UNDEFINED_REMOVED_KEY) {
3239         if (auto removedCacheSession = GetSceneSession(removedCacheId)) {
3240             removedCacheSession->ResetSnapshot();
3241         } else {
3242             TLOGW(WmsLogTag::WMS_PATTERN, "removedCacheSession:%{public}d nullptr", removedCacheId);
3243         }
3244     }
3245 }
3246 
VisitSnapshotFromCache(int32_t persistentId)3247 void SceneSessionManager::VisitSnapshotFromCache(int32_t persistentId)
3248 {
3249     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
3250     if (!snapshotLruCache_->Visit(persistentId)) {
3251         TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d not in cache", persistentId);
3252     }
3253 }
3254 
RemoveSnapshotFromCache(int32_t persistentId)3255 void SceneSessionManager::RemoveSnapshotFromCache(int32_t persistentId)
3256 {
3257     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
3258     snapshotLruCache_->Remove(persistentId);
3259     if (auto sceneSession = GetSceneSession(persistentId)) {
3260         sceneSession->ResetSnapshot();
3261     }
3262 }
3263 
RegisterSaveSnapshotFunc(const sptr<SceneSession> & sceneSession)3264 WSError SceneSessionManager::RegisterSaveSnapshotFunc(const sptr<SceneSession>& sceneSession)
3265 {
3266     if (sceneSession == nullptr) {
3267         TLOGE(WmsLogTag::WMS_PATTERN, "session is nullptr");
3268         return WSError::WS_ERROR_NULLPTR;
3269     }
3270     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3271         return WSError::WS_ERROR_INVALID_WINDOW;
3272     }
3273     auto persistentId = sceneSession->GetPersistentId();
3274     sceneSession->SetSaveSnapshotCallback([this, persistentId]() {
3275         this->PutSnapshotToCache(persistentId);
3276     });
3277     return WSError::WS_OK;
3278 }
3279 
RegisterRemoveSnapshotFunc(const sptr<SceneSession> & sceneSession)3280 WSError SceneSessionManager::RegisterRemoveSnapshotFunc(const sptr<SceneSession>& sceneSession)
3281 {
3282     if (sceneSession == nullptr) {
3283         TLOGE(WmsLogTag::WMS_PATTERN, "session is nullptr");
3284         return WSError::WS_ERROR_NULLPTR;
3285     }
3286     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3287         return WSError::WS_ERROR_INVALID_WINDOW;
3288     }
3289     auto persistentId = sceneSession->GetPersistentId();
3290     sceneSession->SetRemoveSnapshotCallback([this, persistentId]() {
3291         this->RemoveSnapshotFromCache(persistentId);
3292     });
3293     return WSError::WS_OK;
3294 }
3295 
ConfigSupportSnapshotAllSessionStatus()3296 void SceneSessionManager::ConfigSupportSnapshotAllSessionStatus()
3297 {
3298     TLOGI(WmsLogTag::WMS_PATTERN, "support");
3299     auto task = [this] {
3300         systemConfig_.supportSnapshotAllSessionStatus_ = true;
3301     };
3302     taskScheduler_->PostAsyncTask(task, "ConfigSupportSnapshotAllSessionStatus");
3303 }
3304 
CreateUIEffectController(const sptr<IUIEffectControllerClient> & controllerClient,sptr<IUIEffectController> & controller,int32_t & controllerId)3305 WMError SceneSessionManager::CreateUIEffectController(const sptr<IUIEffectControllerClient>& controllerClient,
3306         sptr<IUIEffectController>& controller, int32_t& controllerId)
3307 {
3308     if (!SessionPermission::IsSystemCalling()) {
3309         TLOGE(WmsLogTag::WMS_ANIMATION, "not system calling, permission denied!");
3310         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3311     }
3312     if (!systemConfig_.IsPhoneWindow() && (!systemConfig_.IsPadWindow() || systemConfig_.IsFreeMultiWindowMode())) {
3313         TLOGE(WmsLogTag::WMS_ANIMATION, "device not support!");
3314         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
3315     }
3316     return UIEffectManager::GetInstance().CreateUIEffectController(controllerClient, controller, controllerId);
3317 }
3318 
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot,ScreenLockReason reason)3319 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
3320     const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot, ScreenLockReason reason)
3321 {
3322     auto task = [this, weakSceneSession = wptr(sceneSession), isDelegator, isToDesktop, isSaveSnapshot, reason] {
3323         auto sceneSession = weakSceneSession.promote();
3324         if (sceneSession == nullptr) {
3325             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr");
3326             return WSError::WS_ERROR_NULLPTR;
3327         }
3328         auto persistentId = sceneSession->GetPersistentId();
3329         TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Request background, isDelegator:%{public}d "
3330             "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
3331             persistentId, isDelegator, isToDesktop, isSaveSnapshot);
3332         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
3333         TLOGNI(WmsLogTag::WMS_LIFE, "Notify scene session id: %{public}d paused", sceneSession->GetPersistentId());
3334         sceneSession->UpdateLifecyclePausedInner();
3335         sceneSession->SetActive(false);
3336         sceneSession->UpdatePrivacyModeControlInfo();
3337 
3338         if (isToDesktop) {
3339             sceneSession->EditSessionInfo().callerToken_ = nullptr;
3340             sceneSession->EditSessionInfo().callingTokenId_ = 0;
3341         }
3342 
3343         sceneSession->BackgroundTask(isSaveSnapshot, reason);
3344         listenerController_->NotifySessionLifecycleEvent(
3345             ISessionLifecycleListener::SessionLifecycleEvent::BACKGROUND, sceneSession->GetSessionInfo());
3346         if (!GetSceneSession(persistentId)) {
3347             TLOGNE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
3348             return WSError::WS_ERROR_INVALID_SESSION;
3349         }
3350         if (persistentId == brightnessSessionId_) {
3351             auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
3352             auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
3353             UpdateBrightness(focusedSessionId);
3354         }
3355         if (IsPcSceneSessionLifecycle(sceneSession)) {
3356             TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Notify session background", persistentId);
3357             sceneSession->NotifySessionBackground(1, true, true);
3358         } else {
3359             TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] begin MinimzeUIAbility, system: %{public}u",
3360                 persistentId, static_cast<uint32_t>(sceneSession->GetSessionInfo().isSystem_));
3361             auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
3362             if (!isDelegator) {
3363                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, false,
3364                     static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3365             } else {
3366                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(sceneSessionInfo, true,
3367                     static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3368             }
3369         }
3370 
3371         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3372             WindowInfoReporter::GetInstance().InsertHideReportInfo(sceneSession->GetSessionInfo().bundleName_);
3373         }
3374         return WSError::WS_OK;
3375     };
3376     std::string taskName = "RequestSceneSessionBackground:PID:" +
3377         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
3378     taskScheduler_->PostAsyncTask(task, taskName);
3379     return WSError::WS_OK;
3380 }
3381 
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)3382 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
3383 {
3384     taskScheduler_->PostAsyncTask([this, weakSceneSession = wptr(sceneSession), interactive] {
3385         auto sceneSession = weakSceneSession.promote();
3386         if (sceneSession == nullptr) {
3387             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
3388             return;
3389         }
3390         auto persistentId = sceneSession->GetPersistentId();
3391         TLOGNI(WmsLogTag::WMS_LIFE, "NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
3392         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
3393         if (!GetSceneSession(persistentId)) {
3394             TLOGNE(WmsLogTag::WMS_LIFE, "session is invalid with %{public}d", persistentId);
3395             return;
3396         }
3397         sceneSession->NotifyForegroundInteractiveStatus(interactive);
3398     }, __func__);
3399 }
3400 
DestroyDialogWithMainWindow(const sptr<SceneSession> & sceneSession)3401 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& sceneSession)
3402 {
3403     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
3404     if (sceneSession == nullptr) {
3405         TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
3406         return WSError::WS_ERROR_NULLPTR;
3407     }
3408     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3409         TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", sceneSession->GetPersistentId());
3410         const auto& dialogVec = sceneSession->GetDialogVector();
3411         for (const auto& dialog : dialogVec) {
3412             if (dialog == nullptr) {
3413                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
3414                 continue;
3415             }
3416             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
3417             if (sceneSession == nullptr) {
3418                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
3419                 return WSError::WS_ERROR_INVALID_SESSION;
3420             }
3421             WindowDestroyNotifyVisibility(sceneSession);
3422             dialog->NotifyDestroy();
3423             dialog->Disconnect();
3424 
3425             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
3426             if (dialogSceneSession != nullptr) {
3427                 dialogSceneSession->ClearSpecificSessionCbMap();
3428             }
3429             {
3430                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3431                 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
3432                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
3433                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
3434             }
3435         }
3436         sceneSession->ClearDialogVector();
3437         return WSError::WS_OK;
3438     }
3439     return WSError::WS_ERROR_INVALID_SESSION;
3440 }
3441 
DestroySubSession(const sptr<SceneSession> & sceneSession)3442 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
3443 {
3444     if (sceneSession == nullptr) {
3445         TLOGW(WmsLogTag::WMS_SUB, "sceneSession is nullptr");
3446         return;
3447     }
3448     for (const auto& subSession : sceneSession->GetSubSession()) {
3449         if (subSession != nullptr) {
3450             const auto persistentId = subSession->GetPersistentId();
3451             TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
3452             DestroyAndDisconnectSpecificSessionInner(persistentId);
3453         }
3454     }
3455 }
3456 
DestroyToastSession(const sptr<SceneSession> & sceneSession)3457 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
3458 {
3459     if (sceneSession == nullptr) {
3460         TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
3461         return;
3462     }
3463     for (const auto& toastSession : sceneSession->GetToastSession()) {
3464         if (toastSession != nullptr) {
3465             const auto persistentId = toastSession->GetPersistentId();
3466             TLOGI(WmsLogTag::WMS_TOAST, "id: %{public}d", persistentId);
3467             DestroyAndDisconnectSpecificSessionInner(persistentId);
3468         }
3469     }
3470 }
3471 
BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t fingerId,int32_t action,int32_t wid)3472 void SceneSessionManager::BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3473                                                   int32_t fingerId, int32_t action, int32_t wid)
3474 {
3475     if (pointerEvent == nullptr) {
3476         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null, wid:%{public}d fingerId:%{public}d action:%{public}d",
3477                   wid, fingerId, action);
3478         return;
3479     }
3480     pointerEvent->SetId(CANCEL_POINTER_ID);
3481     pointerEvent->SetTargetWindowId(wid);
3482     pointerEvent->SetPointerId(fingerId);
3483     pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
3484     MMI::PointerEvent::PointerItem item;
3485     item.SetPointerId(fingerId);
3486     pointerEvent->AddPointerItem(item);
3487     if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
3488         pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
3489     } else {
3490         pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
3491     }
3492 }
3493 
SendCancelEventBeforeEraseSession(const sptr<SceneSession> & sceneSession)3494 void SceneSessionManager::SendCancelEventBeforeEraseSession(const sptr<SceneSession>& sceneSession)
3495 {
3496     auto task = [this, needCancelEventSceneSession = sceneSession] {
3497         if (needCancelEventSceneSession == nullptr) {
3498             TLOGI(WmsLogTag::WMS_EVENT, "scenesession is nullptr, needn't send cancel event");
3499             return;
3500         }
3501         auto wid = needCancelEventSceneSession->GetPersistentId();
3502         if (needCancelEventSceneSession->GetMousePointerDownEventStatus()) {
3503             std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
3504             BuildCancelPointerEvent(pointerEvent, 1, MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN, wid);
3505             TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send mouse cancel. wid:%{public}d", wid);
3506             needCancelEventSceneSession->SetMousePointerDownEventStatus(false);
3507             needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
3508         }
3509         std::unordered_set<int32_t> fingerPointerDownStatusList = needCancelEventSceneSession->GetFingerPointerDownStatusList();
3510         if (fingerPointerDownStatusList.empty()) {
3511             return;
3512         }
3513         for (auto fingerId : fingerPointerDownStatusList) {
3514             std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
3515             BuildCancelPointerEvent(pointerEvent, fingerId, MMI::PointerEvent::POINTER_ACTION_DOWN, wid);
3516             TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send touch cancel. wid:%{public}d fingerId:%{public}d",
3517                   wid, fingerId);
3518             needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
3519             needCancelEventSceneSession->RemoveFingerPointerDownStatus(fingerId);
3520         }
3521     };
3522     mainHandler_->PostTask(std::move(task), "wms:sendCancelBeforeEraseSession", 0, AppExecFwk::EventQueue::Priority::VIP);
3523 }
3524 
EraseSceneSessionMapById(int32_t persistentId)3525 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
3526 {
3527     auto sceneSession = GetSceneSession(persistentId);
3528     if (sceneSession != nullptr) {
3529         RemovePreLoadStartingWindowFromMap(sceneSession->GetSessionInfo());
3530     } else {
3531         TLOGW(WmsLogTag::WMS_PATTERN, "session is nullptr id: %{public}d", persistentId);
3532     }
3533     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3534     EraseSceneSessionAndMarkDirtyLocked(persistentId);
3535     systemTopSceneSessionMap_.erase(persistentId);
3536     nonSystemFloatSceneSessionMap_.erase(persistentId);
3537     SendCancelEventBeforeEraseSession(sceneSession);
3538     if (sceneSession && MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
3539         MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
3540         MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
3541     }
3542 }
3543 
3544 /**
3545  * if visible session is erased, mark dirty
3546  * lock-free
3547  */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)3548 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
3549 {
3550     // get scene session lock-free
3551     auto iter = sceneSessionMap_.find(persistentId);
3552     if (iter == sceneSessionMap_.end()) {
3553         TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
3554         return;
3555     }
3556     const auto& sceneSession = iter->second;
3557     if (sceneSession != nullptr && sceneSession->IsVisible()) {
3558         sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
3559     }
3560     sceneSessionMap_.erase(persistentId);
3561 }
3562 
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean,bool isUserRequestedExit)3563 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
3564     bool needRemoveSession, bool isSaveSnapshot, bool isForceClean, bool isUserRequestedExit)
3565 {
3566     auto task = [this, weakSceneSession = wptr(sceneSession), needRemoveSession, isSaveSnapshot, isForceClean,
3567                  isUserRequestedExit]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
3568         auto sceneSession = weakSceneSession.promote();
3569         if (sceneSession == nullptr) {
3570             TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
3571             return WSError::WS_ERROR_NULLPTR;
3572         }
3573         auto persistentId = sceneSession->GetPersistentId();
3574         TLOGNI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Destruct session, remove:%{public}d isSaveSnapshot:%{public}d "
3575             "isForceClean:%{public}d isUserRequestedExit:%{public}d", persistentId, needRemoveSession, isSaveSnapshot,
3576             isForceClean, isUserRequestedExit);
3577         RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
3578         avoidAreaListenerSessionSet_.erase(persistentId);
3579         screenshotAppEventListenerSessionSet_.erase(persistentId);
3580         RemoveSessionFromBlackList(sceneSession);
3581         DestroyDialogWithMainWindow(sceneSession);
3582         DestroyToastSession(sceneSession);
3583         DestroySubSession(sceneSession); // destroy sub session by destruction
3584         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
3585         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3586             WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sceneSession->GetSessionInfo().bundleName_);
3587         }
3588         WindowDestroyNotifyVisibility(sceneSession);
3589         NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
3590         sceneSession->SetRemoveSnapshotCallback([this, persistentId]() {
3591             this->RemoveSnapshotFromCache(persistentId);
3592         });
3593         sceneSession->DisconnectTask(false, isSaveSnapshot);
3594         if (!GetSceneSession(persistentId)) {
3595             TLOGNE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
3596             return WSError::WS_ERROR_INVALID_SESSION;
3597         }
3598         startingWindowRdbMgr_->ClearRdbStore();
3599         auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
3600         sceneSession->GetCloseAbilityWantAndClean(sceneSessionInfo->want);
3601         ResetSceneSessionInfoWant(sceneSessionInfo);
3602         return RequestSceneSessionDestructionInner(
3603             sceneSession, sceneSessionInfo, needRemoveSession, isForceClean, isUserRequestedExit);
3604     };
3605     std::string taskName = "RequestSceneSessionDestruction:PID:" +
3606         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
3607     taskScheduler_->PostAsyncTask(task, taskName);
3608     return WSError::WS_OK;
3609 }
3610 
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)3611 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
3612 {
3613     if (sceneSessionInfo->resultCode == -1) {
3614         AAFwk::Want want;
3615         std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3616         want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3617         sceneSessionInfo->want = std::move(want);
3618         TLOGI(WmsLogTag::WMS_MAIN, "keySessionId: %{public}s", keySessionId.c_str());
3619     }
3620 }
3621 
ResetWantInfo(const sptr<SceneSession> & sceneSession)3622 void SceneSessionManager::ResetWantInfo(const sptr<SceneSession>& sceneSession)
3623 {
3624     if (const auto sessionInfoWant = sceneSession->GetSessionInfo().want) {
3625         const auto& bundleName = sessionInfoWant->GetElement().GetBundleName();
3626         const auto& abilityName = sessionInfoWant->GetElement().GetAbilityName();
3627         const auto& keySessionId = sessionInfoWant->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
3628         AppExecFwk::ElementName element;
3629         element.SetBundleName(bundleName);
3630         element.SetAbilityName(abilityName);
3631         auto want = std::make_shared<AAFwk::Want>();
3632         want->SetElement(element);
3633         want->SetBundle(bundleName);
3634         if (!keySessionId.empty()) {
3635             want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
3636         }
3637         sceneSession->SetSessionInfoWant(want);
3638     }
3639 }
3640 
RequestSceneSessionDestructionInner(sptr<SceneSession> & sceneSession,sptr<AAFwk::SessionInfo> sceneSessionInfo,const bool needRemoveSession,const bool isForceClean,bool isUserRequestedExit)3641 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession,
3642     sptr<AAFwk::SessionInfo> sceneSessionInfo, const bool needRemoveSession, const bool isForceClean,
3643     bool isUserRequestedExit)
3644 {
3645     auto persistentId = sceneSession->GetPersistentId();
3646     TLOGI(WmsLogTag::WMS_MAIN, "[id: %{public}d] Begin CloseUIAbility, system: %{public}d",
3647         persistentId, sceneSession->GetSessionInfo().isSystem_);
3648     if (isForceClean) {
3649         AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(sceneSessionInfo, isUserRequestedExit,
3650             static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3651     } else {
3652         ffrtQueueHelper_->SubmitTask([sceneSessionInfo, persistentId, isUserRequestedExit, where = __func__] {
3653             auto ret = AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(sceneSessionInfo,
3654                 isUserRequestedExit, static_cast<uint32_t>(WindowStateChangeReason::ABILITY_CALL));
3655             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s close ability ret:%{public}d, persistentId:%{public}d",
3656                 where, static_cast<int32_t>(ret), persistentId);
3657         });
3658     }
3659     sceneSession->SetIsUserRequestedExit(isUserRequestedExit);
3660     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
3661     if (needRemoveSession) {
3662         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3663             NotifyClearSession(sceneSession->GetCollaboratorType(), sceneSessionInfo->persistentId);
3664         }
3665         EraseSceneSessionMapById(persistentId);
3666     } else {
3667         // if terminate, reset want. so start from recent, start a new one.
3668         TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
3669         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3670             sceneSession->SetSessionInfoWant(nullptr);
3671         }
3672         ResetWantInfo(sceneSession);
3673         sceneSession->ResetSessionInfoResultCode();
3674         sceneSession->EditSessionInfo().isSetStartWindowType_ = false;
3675     }
3676     NotifySessionForCallback(sceneSession, needRemoveSession);
3677     // Clear js cb map if needed.
3678     sceneSession->ClearJsSceneSessionCbMap(needRemoveSession);
3679     return WSError::WS_OK;
3680 }
3681 
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)3682 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
3683     const sptr<SceneSession>& sceneSession)
3684 {
3685     if (sceneSession == nullptr || sessionStage == nullptr) {
3686         TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
3687         return;
3688     }
3689 
3690     auto remoteObject = sessionStage->AsObject();
3691     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
3692     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
3693         TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
3694         return;
3695     }
3696     TLOGD(WmsLogTag::WMS_LIFE, "Id: %{public}d", sceneSession->GetPersistentId());
3697 }
3698 
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)3699 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
3700 {
3701     taskScheduler_->PostAsyncTask([this, remoteObject] {
3702         auto iter = remoteObjectMap_.find(remoteObject);
3703         if (iter == remoteObjectMap_.end()) {
3704             TLOGNE(WmsLogTag::WMS_DIALOG, "Invalid remoteObject");
3705             return;
3706         }
3707         TLOGND(WmsLogTag::WMS_DIALOG, "Remote died, id: %{public}d", iter->second);
3708         auto sceneSession = GetSceneSession(iter->second);
3709         if (sceneSession == nullptr) {
3710             TLOGNW(WmsLogTag::WMS_DIALOG, "Remote died, session is nullptr, id: %{public}d", iter->second);
3711             return;
3712         }
3713         DestroyAndDisconnectSpecificSessionInner(iter->second);
3714     }, __func__);
3715 }
3716 
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)3717 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3718     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3719     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
3720     SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
3721 {
3722     if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
3723         TLOGE(WmsLogTag::WMS_LIFE, "create system window or modal subwindow permission denied!");
3724         return WSError::WS_ERROR_NOT_SYSTEM_APP;
3725     }
3726     auto parentSession = GetSceneSession(property->GetParentPersistentId());
3727     if (parentSession) {
3728         auto parentProperty = parentSession->GetSessionProperty();
3729         if (parentProperty->GetSubWindowLevel() >= MAX_SUB_WINDOW_LEVEL) {
3730             TLOGE(WmsLogTag::WMS_SUB, "sub window level exceeds limit");
3731             return WSError::WS_ERROR_INVALID_WINDOW;
3732         }
3733         property->SetSubWindowLevel(parentProperty->GetSubWindowLevel() + 1);
3734     }
3735     auto initClientDisplayId = UpdateSpecificSessionClientDisplayId(property);
3736     bool shouldBlock = false;
3737     bool isSystemCalling = SessionPermission::IsSystemCalling();
3738     if (!isSystemCalling) {
3739         if (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && !systemConfig_.IsPcWindow()) {
3740             shouldBlock = property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load();
3741         } else if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && parentSession) {
3742             shouldBlock = parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
3743         }
3744     }
3745     if (shouldBlock) {
3746         TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
3747         return WSError::WS_ERROR_INVALID_OPERATION;
3748     }
3749     bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
3750     if (!isPhoneOrPad && property->GetWindowType() == WindowType::WINDOW_TYPE_MUTISCREEN_COLLABORATION) {
3751         TLOGE(WmsLogTag::WMS_LIFE, "only phone or pad can create mutiScreen collaboration window");
3752         return WSError::WS_ERROR_INVALID_OPERATION;
3753     }
3754 
3755     if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
3756         WSError err = CheckSubSessionStartedByExtensionAndSetDisplayId(token, property, sessionStage);
3757         if (err != WSError::WS_OK) {
3758             return err;
3759         }
3760     }
3761     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
3762     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
3763         TLOGE(WmsLogTag::DEFAULT, "The alarm window has been deprecated!");
3764         return WSError::WS_ERROR_INVALID_WINDOW;
3765     }
3766 
3767     if (property->GetWindowType() == WindowType::WINDOW_TYPE_FB) {
3768         auto ret = IsFloatingBallValid(parentSession);
3769         if (ret != WSError::WS_OK) {
3770             return ret;
3771         }
3772     }
3773 
3774     TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
3775         property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
3776 
3777     // Get pid and uid before posting task.
3778     auto pid = IPCSkeleton::GetCallingRealPid();
3779     auto uid = IPCSkeleton::GetCallingUid();
3780     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &persistentId, &session, &systemConfig, token,
3781                  pid, uid, isSystemCalling, initClientDisplayId]() {
3782         if (property == nullptr) {
3783             TLOGNE(WmsLogTag::WMS_LIFE, "property is nullptr");
3784             return WSError::WS_ERROR_NULLPTR;
3785         }
3786         if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !IsEnablePiPCreate(property)) {
3787             TLOGNE(WmsLogTag::WMS_PIP, "pip window is not enable to create.");
3788             return WSError::WS_DO_NOTHING;
3789         }
3790         const auto type = property->GetWindowType();
3791         // create specific session
3792         SessionInfo info;
3793         info.windowType_ = static_cast<uint32_t>(type);
3794         info.bundleName_ = property->GetSessionInfo().bundleName_;
3795         info.abilityName_ = property->GetSessionInfo().abilityName_;
3796         info.moduleName_ = property->GetSessionInfo().moduleName_;
3797         info.screenId_ = property->GetDisplayId();
3798 
3799         if (IsPiPForbidden(property, type)) {
3800             TLOGNE(WmsLogTag::WMS_PIP, "forbid pip");
3801             return WSError::WS_ERROR_INVALID_PERMISSION;
3802         }
3803         ClosePipWindowIfExist(type);
3804         sptr<SceneSession> newSession = RequestSceneSession(info, property);
3805         if (newSession == nullptr) {
3806             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
3807             return WSError::WS_ERROR_NULLPTR;
3808         }
3809         newSession->SetClientDisplayId(initClientDisplayId);
3810         property->SetSystemCalling(isSystemCalling);
3811         auto errCode = newSession->ConnectInner(
3812             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
3813         newSession->SetIsSystemSpecificSession(isSystemCalling);
3814         systemConfig = systemConfig_;
3815         persistentId = property->GetPersistentId();
3816 
3817         NotifyCreateSpecificSession(newSession, property, type);
3818         session = newSession;
3819         AddClientDeathRecipient(sessionStage, newSession);
3820 
3821         if (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
3822             CheckFloatWindowIsAnco(pid, newSession);
3823         }
3824 
3825         UpdateSubSessionBlackList(newSession);
3826         TLOGNI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
3827             "parentId: %{public}d, type: %{public}d",
3828             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
3829         return errCode;
3830     };
3831 
3832     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
3833 }
3834 
CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject> & token,const sptr<WindowSessionProperty> & property,const sptr<ISessionStage> & sessionStage)3835 WSError SceneSessionManager::CheckSubSessionStartedByExtensionAndSetDisplayId(const sptr<IRemoteObject>& token,
3836     const sptr<WindowSessionProperty>& property, const sptr<ISessionStage>& sessionStage)
3837 {
3838     sptr<SceneSession> extensionParentSession = GetSceneSession(property->GetParentPersistentId());
3839     if (extensionParentSession == nullptr) {
3840         TLOGE(WmsLogTag::WMS_UIEXT, "extensionParentSession is invalid with %{public}d",
3841             property->GetParentPersistentId());
3842         return WSError::WS_ERROR_NULLPTR;
3843     }
3844     auto pid = IPCSkeleton::GetCallingRealPid();
3845     auto parentPid = extensionParentSession->GetCallingPid();
3846     WSError result = WSError::WS_ERROR_INVALID_WINDOW;
3847     if (pid == parentPid) { // Determine Whether to create a sub window in the same process.
3848         TLOGI(WmsLogTag::WMS_UIEXT, "pid == parentPid");
3849         result = WSError::WS_OK;
3850     }
3851     AAFwk::UIExtensionSessionInfo info;
3852     AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
3853     if (info.persistentId != INVALID_SESSION_ID && info.hostWindowId != INVALID_SESSION_ID) {
3854         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
3855         // Check the parent ids are the same in cross-process scenarios.
3856         if (parentId == property->GetParentPersistentId()) {
3857             TLOGD(WmsLogTag::WMS_UIEXT, "parentId == property->GetParentPersistentId(parentId:%{public}d)", parentId);
3858             result = WSError::WS_OK;
3859         }
3860     }
3861     if (SessionPermission::IsSystemCalling()) { // Fallback strategy.
3862         TLOGD(WmsLogTag::WMS_UIEXT, "is system app");
3863         result = WSError::WS_OK;
3864     }
3865     if (property->GetIsUIExtensionAbilityProcess() && SessionPermission::IsStartedByUIExtension()) {
3866         AAFwk::UIExtensionHostInfo hostInfo;
3867         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
3868         const auto& sessionInfo = extensionParentSession->GetSessionInfo();
3869         auto hostBundleName = extensionParentSession->IsAnco()?
3870             SessionUtils::GetBundleNameBySessionName(hostInfo.sessionName) : hostInfo.elementName_.GetBundleName();
3871         if (sessionInfo.bundleName_ != hostBundleName &&
3872             sessionInfo.bundleName_ != info.hostElementName.GetBundleName()) {
3873             TLOGE(WmsLogTag::WMS_UIEXT, "The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s,"
3874                 " hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(), hostBundleName.c_str());
3875             ReportSubWindowCreationFailure(pid, info.elementName.GetAbilityName(), sessionInfo.bundleName_,
3876                 hostBundleName);
3877             return WSError::WS_ERROR_INVALID_WINDOW;
3878         }
3879         result = WSError::WS_OK;
3880     }
3881     if (result == WSError::WS_OK) {
3882         sptr<WindowSessionProperty> parentProperty = extensionParentSession->GetSessionProperty();
3883         if (sessionStage && property->GetIsUIExtFirstSubWindow()) {
3884             sessionStage->UpdateDisplayId(extensionParentSession->GetClientDisplayId() == VIRTUAL_DISPLAY_ID
3885                                               ? VIRTUAL_DISPLAY_ID
3886                                               : parentProperty->GetDisplayId());
3887             property->SetDisplayId(parentProperty->GetDisplayId());
3888         }
3889     } else {
3890         TLOGE(WmsLogTag::WMS_UIEXT, "can't create sub window: persistentId %{public}d", property->GetPersistentId());
3891     }
3892     return result;
3893 }
3894 
ReportSubWindowCreationFailure(const int32_t & pid,const std::string & abilityName,const std::string & parentBundleName,const std::string & hostBundleName)3895 void SceneSessionManager::ReportSubWindowCreationFailure(const int32_t& pid, const std::string& abilityName,
3896         const std::string& parentBundleName, const std::string& hostBundleName)
3897 {
3898     taskScheduler_->PostAsyncTask([pid, abilityName, parentBundleName, hostBundleName]() {
3899         std::ostringstream oss;
3900         oss << "The hostWindow is not this parentwindow ! parentwindow bundleName: " << parentBundleName;
3901         oss << ", hostwindow bundleName: " << hostBundleName;
3902         oss << ", abilityName: " << abilityName;
3903         SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(
3904             static_cast<int32_t>(WindowDFXHelperType::WINDOW_CREATE_SUB_WINDOW_FAILED), pid, oss.str());
3905     }, __func__);
3906 }
3907 
CheckFloatWindowIsAnco(pid_t pid,const sptr<SceneSession> & newSession)3908 void SceneSessionManager::CheckFloatWindowIsAnco(pid_t pid, const sptr<SceneSession>& newSession)
3909 {
3910     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
3911     {
3912         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3913         sceneSessionMapCopy = sceneSessionMap_;
3914     }
3915     for (const auto& [_, session] : sceneSessionMapCopy) {
3916         if (session && session->GetCallingPid() == pid &&
3917             session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
3918             auto sessionInfo = session->GetSessionInfo();
3919             if (AbilityInfoManager::GetInstance().IsAnco(sessionInfo.bundleName_,
3920                     sessionInfo.abilityName_, sessionInfo.moduleName_)) {
3921                 newSession->SetIsAncoForFloatingWindow(true);
3922                 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Set float window is anco, wid: %{public}d", newSession->GetWindowId());
3923                 break;
3924             }
3925         }
3926     }
3927 }
3928 
ClosePipWindowIfExist(WindowType type)3929 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
3930 {
3931     if (type != WindowType::WINDOW_TYPE_PIP) {
3932         return;
3933     }
3934     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3935     for (const auto& [_, session] : sceneSessionMap_) {
3936         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
3937             session->NotifyCloseExistPipWindow();
3938             break;
3939         }
3940     }
3941 }
3942 
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo,DisplayId displayId)3943 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo, DisplayId displayId)
3944 {
3945     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3946     for (const auto& [_, session] : sceneSessionMap_) {
3947         if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
3948             pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
3949             session->IsSessionForeground()) {
3950             if (startPiPFailedFunc_) {
3951                 startPiPFailedFunc_(displayId);
3952             }
3953             TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
3954             return false;
3955         }
3956     }
3957     return true;
3958 }
3959 
IsEnablePiPCreate(const sptr<WindowSessionProperty> & property)3960 bool SceneSessionManager::IsEnablePiPCreate(const sptr<WindowSessionProperty>& property)
3961 {
3962     if (isScreenLocked_) {
3963         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
3964         return false;
3965     }
3966     Rect pipRect = property->GetRequestRect();
3967     if (pipRect.width_ == 0 || pipRect.height_ == 0) {
3968         TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
3969         return false;
3970     }
3971     if (!CheckPiPPriority(property->GetPiPTemplateInfo(), property->GetDisplayId())) {
3972         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
3973         return false;
3974     }
3975     auto parentSession = GetSceneSession(property->GetParentPersistentId());
3976     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
3977         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
3978         return false;
3979     }
3980     return true;
3981 }
3982 
IsPiPForbidden(const sptr<WindowSessionProperty> & property,const WindowType & type)3983 bool SceneSessionManager::IsPiPForbidden(const sptr<WindowSessionProperty>& property, const WindowType& type)
3984 {
3985     sptr<SceneSession> parentSession = GetSceneSession(property->GetParentPersistentId());
3986     if (parentSession == nullptr) {
3987         TLOGE(WmsLogTag::WMS_PIP, "invalid parentSession");
3988         return false;
3989     }
3990     sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
3991     if (parentProperty == nullptr) {
3992         TLOGE(WmsLogTag::WMS_PIP, "invalid parentProperty");
3993         return false;
3994     }
3995     DisplayId screenId = parentProperty->GetDisplayId();
3996     if (screenId == SCREEN_ID_INVALID) {
3997         TLOGE(WmsLogTag::WMS_PIP, "invalid screenId");
3998         return false;
3999     }
4000     sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSession(screenId);
4001     if (screenSession == nullptr) {
4002         TLOGE(WmsLogTag::WMS_PIP, "invalid screenSession");
4003         return false;
4004     }
4005     std::string screenName = screenSession->GetName();
4006     if (type == WindowType::WINDOW_TYPE_PIP &&
4007        (screenName == "HiCar" || screenName == "SuperLauncher" || screenName == "PadWithCar")) {
4008         TLOGI(WmsLogTag::WMS_PIP, "screen name %{public}s", screenName.c_str());
4009         return true;
4010     }
4011     return false;
4012 }
4013 
IsFloatingBallValid(const sptr<SceneSession> & parentSession)4014 WSError SceneSessionManager::IsFloatingBallValid(const sptr<SceneSession>& parentSession)
4015 {
4016     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
4017         parentSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
4018         TLOGE(WmsLogTag::WMS_LIFE, "Parent is null or state invalid");
4019         return WSError::WS_ERROR_INVALID_PARENT;
4020     }
4021     return WSError::WS_OK;
4022 }
4023 
NotifyPiPWindowVisibleChange(bool screenLocked)4024 void SceneSessionManager::NotifyPiPWindowVisibleChange(bool screenLocked) {
4025     sptr<SceneSession> session = SelectSesssionFromMap(pipWindowSurfaceId_);
4026     if (session != nullptr) {
4027         std::vector<std::pair<uint64_t, WindowVisibilityState>> pipVisibilityChangeInfos;
4028         if (screenLocked) {
4029             pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
4030         } else {
4031             pipVisibilityChangeInfos.emplace_back(pipWindowSurfaceId_, WINDOW_VISIBILITY_STATE_NO_OCCLUSION);
4032         }
4033         DealwithVisibilityChange(pipVisibilityChangeInfos, lastVisibleData_);
4034     }
4035 }
4036 
IsLastPiPWindowVisible(uint64_t surfaceId,WindowVisibilityState lastVisibilityState)4037 bool SceneSessionManager::IsLastPiPWindowVisible(uint64_t surfaceId, WindowVisibilityState lastVisibilityState) {
4038     sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
4039     if (session == nullptr || session->GetWindowMode() != WindowMode::WINDOW_MODE_PIP) {
4040         TLOGD(WmsLogTag::WMS_PIP, "session is null or windowMode is not PIP");
4041         return false;
4042     }
4043     if (isScreenLocked_) {
4044         TLOGD(WmsLogTag::WMS_PIP, "pipWindow occlusion because of screen locked");
4045         return false;
4046     }
4047     if (lastVisibilityState != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
4048         // no visibility notification processing after pip is occlusion
4049         TLOGI(WmsLogTag::WMS_PIP, "pipWindow occlusion success. pipWindowSurfaceId: %{public}" PRIu64, surfaceId);
4050         pipWindowSurfaceId_ = surfaceId;
4051         return true;
4052     }
4053     return false;
4054 }
4055 
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)4056 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
4057 {
4058     WindowType type = property->GetWindowType();
4059     if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
4060         return true;
4061     }
4062 
4063     if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
4064         TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
4065         return false;
4066     }
4067 
4068     if (!SessionPermission::IsSystemCalling()) {
4069         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
4070         return false;
4071     }
4072 
4073     return true;
4074 }
4075 
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)4076 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
4077 {
4078     WindowType type = property->GetWindowType();
4079     if (WindowHelper::IsUIExtensionWindow(type)) {
4080         // UIExtension window disallowed.
4081         return false;
4082     }
4083     if (!WindowHelper::IsSystemWindow(type)) {
4084         // type is not system
4085         return true;
4086     }
4087     if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && property->IsSystemKeyboard()) {
4088         // system keyboard window can only be created by virtual keyboard service
4089         if (SessionPermission::VerifyCallingPermission("ohos.permission.VIRTUAL_KEYBOARD_WINDOW")) {
4090             TLOGD(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check sucess.");
4091             return true;
4092         }
4093         TLOGE(WmsLogTag::WMS_KEYBOARD, "create system keyboard, permission check failed.");
4094         return false;
4095     }
4096     if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
4097          type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) && SessionPermission::IsStartedByInputMethod()) {
4098         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
4099         TLOGD(WmsLogTag::WMS_KEYBOARD, "check create permission success, input method app create input method window.");
4100         return true;
4101     }
4102     if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
4103         // some system types could be created by normal app
4104         return true;
4105     }
4106     if (type == WindowType::WINDOW_TYPE_FB) {
4107         return SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_FLOATING_BALL);
4108     }
4109     if (type == WindowType::WINDOW_TYPE_FLOAT) {
4110         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
4111         if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
4112             (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd() ||
4113                 systemConfig_.supportTypeFloatWindow_)) {
4114             TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission success.");
4115             return true;
4116         } else if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
4117             systemConfig_.supportCreateFloatWindow_) {
4118             TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission success. SupportCreateFloatWindow.");
4119             return true;
4120         } else {
4121             TLOGI(WmsLogTag::WMS_SYSTEM, "check float permission failed.");
4122             return false;
4123         }
4124     }
4125     if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
4126         int32_t parentId = property->GetParentPersistentId();
4127         auto parentSession = GetSceneSession(parentId);
4128         if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
4129             SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
4130             TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
4131             return true;
4132         } else {
4133             TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
4134         }
4135     }
4136     if (SessionHelper::IsNeedSACalling(type)) {
4137         if (SessionPermission::IsSACalling()) {
4138             TLOGI(WmsLogTag::WMS_SYSTEM, "check sa permission success, create with SA calling.");
4139             return true;
4140         }
4141         TLOGE(WmsLogTag::WMS_SYSTEM, "check sa permission failed");
4142         return false;
4143     }
4144     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
4145         TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
4146         return true;
4147     }
4148     TLOGE(WmsLogTag::WMS_SYSTEM, "finally check permission failed.");
4149     return false;
4150 }
4151 
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)4152 void SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
4153 {
4154     if (property == nullptr) {
4155         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
4156         return;
4157     }
4158     SessionInfo& sessionInfo = property->EditSessionInfo();
4159     sessionInfo.persistentId_ = property->GetPersistentId();
4160     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
4161     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
4162     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
4163     sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
4164                                     ? SessionState::STATE_ACTIVE
4165                                     : SessionState::STATE_BACKGROUND;
4166     sessionInfo.isPersistentRecover_ = true;
4167     sessionInfo.appInstanceKey_ = property->GetAppInstanceKey();
4168     sessionInfo.screenId_ = property->GetDisplayId();
4169     sessionInfo.isAbilityHook_ = property->GetIsAbilityHook();
4170     sessionInfo.supportedWindowModes =
4171         WindowHelper::ConvertSupportTypeToSupportModes(property->GetWindowModeSupportType());
4172     TLOGI(WmsLogTag::WMS_RECOVER,
4173         "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
4174         "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
4175         "windowState=%{public}u, appInstanceKey=%{public}s, isFollowParentMultiScreenPolicy=%{public}d, "
4176         "screenId=%{public}" PRIu64 ", isAbilityHook=%{public}d",
4177         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
4178         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_,
4179         sessionInfo.appInstanceKey_.c_str(), sessionInfo.isFollowParentMultiScreenPolicy,
4180         sessionInfo.screenId_, sessionInfo.isAbilityHook_);
4181 }
4182 
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)4183 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
4184 {
4185     TLOGI(WmsLogTag::WMS_RECOVER, "Size of PersistentIds need to be recovered=%{public}zu, CurrentUserId=%{public}d",
4186         alivePersistentIds.size(), currentUserId_.load());
4187     alivePersistentIds_ = alivePersistentIds;
4188 }
4189 
IsNeedRecover(const int32_t persistentId)4190 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
4191 {
4192     if (auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
4193         it == alivePersistentIds_.end()) {
4194         TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
4195         return false;
4196     }
4197     return true;
4198 }
4199 
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)4200 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
4201     bool isSpecificSession)
4202 {
4203     if (property == nullptr) {
4204         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
4205         return WSError::WS_ERROR_NULLPTR;
4206     }
4207     if (!CheckSystemWindowPermission(property)) {
4208         TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
4209         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4210     }
4211     if (isSpecificSession) {
4212         if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
4213             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
4214             return WSError::WS_ERROR_INVALID_PARAM;
4215         }
4216     } else {
4217         if (property->GetPersistentId() > 0 && !IsNeedRecover(property->GetPersistentId())) {
4218             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
4219             return WSError::WS_ERROR_INVALID_PARAM;
4220         }
4221     }
4222     return WSError::WS_OK;
4223 }
4224 
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)4225 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
4226     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
4227     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
4228 {
4229     auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
4230     if (propCheckRet != WSError::WS_OK) {
4231         return propCheckRet;
4232     }
4233     auto pid = IPCSkeleton::GetCallingRealPid();
4234     auto uid = IPCSkeleton::GetCallingUid();
4235     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
4236         if (recoveringFinished_ || sessionRecoverStateChangeFunc_ == nullptr) {
4237             TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
4238             return WSError::WS_ERROR_INVALID_OPERATION;
4239         }
4240         sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_START_RECONNECT, property);
4241         SessionInfo info = property->GetSessionInfo();
4242         TLOGNI(WmsLogTag::WMS_RECOVER, "callingWindowId=%{public}" PRIu32, property->GetCallingSessionId());
4243         ClosePipWindowIfExist(property->GetWindowType());
4244         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
4245         if (sceneSession == nullptr) {
4246             TLOGNE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
4247             sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4248             return WSError::WS_ERROR_NULLPTR;
4249         }
4250 
4251         auto persistentId = sceneSession->GetPersistentId();
4252         if (persistentId != info.persistentId_) {
4253             TLOGNE(WmsLogTag::WMS_RECOVER,
4254                 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
4255                 info.persistentId_, persistentId, property->GetParentPersistentId());
4256             failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
4257             EraseSceneSessionMapById(persistentId);
4258             sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4259             return WSError::WS_ERROR_INVALID_SESSION;
4260         }
4261 
4262         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
4263         if (errCode != WSError::WS_OK) {
4264             TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
4265             EraseSceneSessionMapById(persistentId);
4266             sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4267             return errCode;
4268         }
4269         sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_FINISH_RECONNECT, property);
4270         AddClientDeathRecipient(sessionStage, sceneSession);
4271         session = sceneSession;
4272         return errCode;
4273     };
4274     return taskScheduler_->PostSyncTask(task, __func__);
4275 }
4276 
NotifyRecoveringFinished()4277 void SceneSessionManager::NotifyRecoveringFinished()
4278 {
4279     taskScheduler_->PostAsyncTask([this]() {
4280         TLOGNI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
4281         recoveringFinished_ = true;
4282         recoverSubSessionCacheMap_.clear();
4283         recoverDialogSessionCacheMap_.clear();
4284     }, __func__);
4285 }
4286 
CacheSpecificSessionForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4287 void SceneSessionManager::CacheSpecificSessionForRecovering(
4288     const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
4289 {
4290     if (!IsWindowSupportCacheForRecovering(sceneSession, property)) {
4291         return;
4292     }
4293 
4294     auto windowType = property->GetWindowType();
4295     auto parentId = property->GetParentPersistentId();
4296     TLOGI(WmsLogTag::WMS_RECOVER, "Cache specific session persistentId=%{public}d, parent persistentId="
4297         "%{public}d, window type=%{public}d", sceneSession->GetPersistentId(), parentId, windowType);
4298 
4299     if (WindowHelper::IsSubWindow(windowType)) {
4300         recoverSubSessionCacheMap_[parentId].emplace_back(sceneSession);
4301     } else if (WindowHelper::IsDialogWindow(windowType)) {
4302         recoverDialogSessionCacheMap_[parentId].emplace_back(sceneSession);
4303     }
4304 }
4305 
IsWindowSupportCacheForRecovering(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4306 bool SceneSessionManager::IsWindowSupportCacheForRecovering(
4307     const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)
4308 {
4309     if (recoveringFinished_) {
4310         TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
4311         return false;
4312     }
4313 
4314     if (sceneSession == nullptr || property == nullptr) {
4315         TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
4316         return false;
4317     }
4318 
4319     auto windowType = property->GetWindowType();
4320     if (!WindowHelper::IsSubWindow(windowType) && !WindowHelper::IsDialogWindow(windowType)) {
4321         return false;
4322     }
4323 
4324     auto parentId = property->GetParentPersistentId();
4325     if ((WindowHelper::IsSubWindow(windowType) &&
4326          createSubSessionFuncMap_.find(parentId) != createSubSessionFuncMap_.end()) ||
4327         (WindowHelper::IsDialogWindow(windowType) &&
4328          bindDialogTargetFuncMap_.find(parentId) != bindDialogTargetFuncMap_.end())) {
4329         return false;
4330     }
4331 
4332     return true;
4333 }
4334 
RecoverCachedSubSession(int32_t persistentId)4335 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
4336 {
4337     auto iter = recoverSubSessionCacheMap_.find(persistentId);
4338     if (iter == recoverSubSessionCacheMap_.end()) {
4339         return;
4340     }
4341     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
4342     for (auto& sceneSession : iter->second) {
4343         NotifyCreateSubSession(persistentId, sceneSession);
4344     }
4345     recoverSubSessionCacheMap_.erase(iter);
4346 }
4347 
RecoverCachedDialogSession(int32_t persistentId)4348 void SceneSessionManager::RecoverCachedDialogSession(int32_t persistentId)
4349 {
4350     auto iter = recoverDialogSessionCacheMap_.find(persistentId);
4351     if (iter == recoverDialogSessionCacheMap_.end()) {
4352         return;
4353     }
4354     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
4355     for (auto& sceneSession : iter->second) {
4356         UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
4357     }
4358     recoverDialogSessionCacheMap_.erase(iter);
4359 }
4360 
NotifySessionUnfocusedToClient(int32_t persistentId)4361 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
4362 {
4363     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
4364     listenerController_->NotifySessionUnfocused(persistentId);
4365 }
4366 
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)4367 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
4368     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
4369     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
4370 {
4371     auto result = CheckSessionPropertyOnRecovery(property, false);
4372     if (result != WSError::WS_OK) {
4373         return result;
4374     }
4375     auto pid = IPCSkeleton::GetCallingRealPid();
4376     auto uid = IPCSkeleton::GetCallingUid();
4377     auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
4378         if (recoveringFinished_ || sessionRecoverStateChangeFunc_ == nullptr) {
4379             TLOGNW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
4380             return WSError::WS_ERROR_INVALID_OPERATION;
4381         }
4382         if (recoverSceneSessionFunc_ == nullptr) {
4383             TLOGNE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
4384             return WSError::WS_ERROR_NULLPTR;
4385         }
4386         sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_START_RECONNECT, property);
4387         SessionInfo sessionInfo = property->GetSessionInfo();
4388         sptr<SceneSession> sceneSession = RequestSceneSession(sessionInfo, nullptr);
4389         if (sceneSession == nullptr) {
4390             TLOGNE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
4391             sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4392             return WSError::WS_ERROR_NULLPTR;
4393         }
4394         int32_t persistentId = sceneSession->GetPersistentId();
4395         if (persistentId != sessionInfo.persistentId_) {
4396             TLOGNE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
4397                 sessionInfo.persistentId_, persistentId);
4398             EraseSceneSessionMapById(persistentId);
4399             sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4400             return WSError::WS_ERROR_INVALID_SESSION;
4401         }
4402         auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
4403         if (ret != WSError::WS_OK) {
4404             TLOGNE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
4405             EraseSceneSessionMapById(sessionInfo.persistentId_);
4406             sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_NOT_RECONNECT, property);
4407             return ret;
4408         }
4409         sessionRecoverStateChangeFunc_(SessionRecoverState::SESSION_FINISH_RECONNECT, property);
4410         session = sceneSession;
4411         return WSError::WS_OK;
4412     };
4413     return taskScheduler_->PostSyncTask(task, __func__);
4414 }
4415 
UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty> & property)4416 void SceneSessionManager::UpdateRecoverPropertyForSuperFold(const sptr<WindowSessionProperty>& property)
4417 {
4418     if (property->GetDisplayId() != VIRTUAL_DISPLAY_ID) {
4419         return;
4420     }
4421     static auto foldCreaseRegion = SingletonContainer::Get<DisplayManager>().GetCurrentFoldCreaseRegion();
4422     if (foldCreaseRegion == nullptr) {
4423         return;
4424     }
4425     Rect recoverWindowRect = property->GetWindowRect();
4426     Rect recoverRequestRect = property->GetRequestRect();
4427     TLOGD(WmsLogTag::WMS_RECOVER,
4428         "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
4429         recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
4430         static_cast<uint32_t>(property->GetDisplayId()));
4431 
4432     auto foldCrease = foldCreaseRegion->GetCreaseRects().front();
4433     recoverWindowRect.posY_ += foldCrease.posY_ + static_cast<int32_t>(foldCrease.height_);
4434     recoverRequestRect.posY_ += foldCrease.posY_ + static_cast<int32_t>(foldCrease.height_);
4435     property->SetWindowRect(recoverWindowRect);
4436     property->SetRequestRect(recoverRequestRect);
4437     property->SetDisplayId(0);
4438     TLOGD(WmsLogTag::WMS_RECOVER,
4439         "WindowRect: %{public}s, RequestRect: %{public}s, DisplayId: %{public}d",
4440         recoverWindowRect.ToString().c_str(), recoverRequestRect.ToString().c_str(),
4441         static_cast<uint32_t>(property->GetDisplayId()));
4442 }
4443 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)4444 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
4445 {
4446     TLOGI(WmsLogTag::WMS_RECOVER, "in");
4447     recoverSceneSessionFunc_ = func;
4448 }
4449 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)4450 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
4451 {
4452     createSystemSessionFunc_ = func;
4453 }
4454 
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)4455 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
4456 {
4457     createKeyboardSessionFunc_ = func;
4458 }
4459 
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)4460 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
4461 {
4462     startPiPFailedFunc_ = std::move(func);
4463 }
4464 
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)4465 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
4466     const NotifyCreateSubSessionFunc& func)
4467 {
4468     TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
4469     taskScheduler_->PostSyncTask([this, persistentId, func]() {
4470         createSubSessionFuncMap_[persistentId] = func;
4471         RecoverCachedSubSession(persistentId);
4472         return WMError::WM_OK;
4473     }, __func__);
4474 }
4475 
RegisterBindDialogTargetListener(const sptr<SceneSession> & session,NotifyBindDialogSessionFunc && func)4476 void SceneSessionManager::RegisterBindDialogTargetListener(const sptr<SceneSession>& session,
4477     NotifyBindDialogSessionFunc&& func)
4478 {
4479     int32_t persistentId = session->GetPersistentId();
4480     TLOGI(WmsLogTag::WMS_DIALOG, "Id: %{public}d", persistentId);
4481     taskScheduler_->PostTask([this, session, persistentId, func = std::move(func)] {
4482         session->RegisterBindDialogSessionCallback(func);
4483         bindDialogTargetFuncMap_[persistentId] = std::move(func);
4484         RecoverCachedDialogSession(persistentId);
4485     }, __func__);
4486 }
4487 
SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession> & newSession)4488 void SceneSessionManager::SetFocusedSessionDisplayIdIfNeeded(sptr<SceneSession>& newSession)
4489 {
4490     if (newSession->GetSessionProperty()->GetDisplayId() == DISPLAY_ID_INVALID) {
4491         uint64_t defaultDisplayId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
4492         int32_t focusSessionId = windowFocusController_->GetFocusedSessionId(defaultDisplayId);
4493         auto focusedSession = GetSceneSession(focusSessionId);
4494         DisplayId displayId = defaultDisplayId;
4495         if (focusedSession != nullptr && focusedSession->GetSessionProperty()->GetDisplayId() != DISPLAY_ID_INVALID) {
4496             displayId = focusedSession->GetSessionProperty()->GetDisplayId();
4497             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "id: %{public}d, focus id %{public}d, display id: %{public}" PRIu64,
4498                 newSession->GetPersistentId(), focusedSession->GetPersistentId(), displayId);
4499         } else {
4500             TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get focus id failed, use default displayId %{public}" PRIu64, displayId);
4501         }
4502         newSession->SetScreenId(displayId);
4503         newSession->GetSessionProperty()->SetDisplayId(displayId);
4504     }
4505 }
4506 
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)4507 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
4508     sptr<WindowSessionProperty> property, const WindowType& type)
4509 {
4510     if (newSession == nullptr || property == nullptr) {
4511         TLOGE(WmsLogTag::WMS_LIFE, "newSession or property is nullptr");
4512         return;
4513     }
4514     if (SessionHelper::IsSystemWindow(type)) {
4515         if (type == WindowType::WINDOW_TYPE_FLOAT) {
4516             auto parentSession = GetSceneSession(property->GetParentPersistentId());
4517             if (parentSession != nullptr) {
4518                 newSession->SetParentSession(parentSession);
4519             }
4520         }
4521         if (type == WindowType::WINDOW_TYPE_TOAST) {
4522             NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
4523         }
4524         if (type != WindowType::WINDOW_TYPE_DIALOG) {
4525             if (WindowHelper::IsSystemSubWindow(type)) {
4526                 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
4527             } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
4528                 && createKeyboardSessionFunc_) {
4529                 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
4530             } else if (createSystemSessionFunc_) {
4531                 SetFocusedSessionDisplayIdIfNeeded(newSession);
4532                 property->SetDisplayId(newSession->GetSessionProperty()->GetDisplayId());
4533                 createSystemSessionFunc_(newSession);
4534             }
4535             TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
4536                 newSession->GetPersistentId(), type);
4537         } else {
4538             TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, "
4539                 "type:%{public}d", newSession->GetPersistentId(), type);
4540             return;
4541         }
4542     } else if (SessionHelper::IsSubWindow(type)) {
4543         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
4544         TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
4545             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
4546     } else {
4547         TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
4548             newSession->GetPersistentId(), type);
4549     }
4550 }
4551 
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)4552 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
4553 {
4554     if (session == nullptr) {
4555         TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
4556         return;
4557     }
4558     auto iter = createSubSessionFuncMap_.find(persistentId);
4559     if (iter == createSubSessionFuncMap_.end()) {
4560         recoverSubSessionCacheMap_[persistentId].push_back(session);
4561         TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
4562         return;
4563     }
4564     const auto& createSubSessionFunc = iter->second;
4565     sptr<SceneSession> parentSession = nullptr;
4566     if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
4567         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4568         parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
4569     } else {
4570         parentSession = GetSceneSession(persistentId);
4571     }
4572     if (parentSession == nullptr) {
4573         TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
4574             persistentId, session->GetPersistentId());
4575         return;
4576     }
4577     parentSession->AddSubSession(session);
4578     session->SetParentSession(parentSession);
4579     if (createSubSessionFunc) {
4580         createSubSessionFunc(session);
4581     }
4582     TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, subId: %{public}d",
4583         persistentId, session->GetPersistentId());
4584 }
4585 
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)4586 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
4587     const std::map<int32_t, sptr<SceneSession>>& sessionMap)
4588 {
4589     if (persistentId == INVALID_SESSION_ID) {
4590         TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
4591         return nullptr;
4592     }
4593     auto iter = sessionMap.find(persistentId);
4594     if (iter == sessionMap.end()) {
4595         TLOGD(WmsLogTag::WMS_LIFE, "Error found scene session with id: %{public}d", persistentId);
4596         return nullptr;
4597     }
4598     sptr<SceneSession> parentSession = iter->second;
4599     if (parentSession == nullptr) {
4600         TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
4601         return nullptr;
4602     }
4603     bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
4604         parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
4605     if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
4606         TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
4607         return parentSession;
4608     }
4609     return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
4610 }
4611 
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)4612 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
4613 {
4614     if (session == nullptr) {
4615         TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
4616         return;
4617     }
4618 
4619     auto parentSession = GetSceneSession(persistentId);
4620     if (parentSession == nullptr) {
4621         TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
4622             persistentId, session->GetPersistentId());
4623         return;
4624     }
4625     parentSession->AddToastSession(session);
4626     session->SetParentSession(parentSession);
4627     TLOGD(WmsLogTag::WMS_LIFE, "Notify success, parentId: %{public}d, toastId: %{public}d",
4628         persistentId, session->GetPersistentId());
4629 }
4630 
UnregisterSpecificSessionCreateListener(int32_t persistentId)4631 void SceneSessionManager::UnregisterSpecificSessionCreateListener(int32_t persistentId)
4632 {
4633     TLOGI(WmsLogTag::WMS_SUB, "id: %{public}d", persistentId);
4634     taskScheduler_->PostSyncTask([this, persistentId]() {
4635         if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
4636             createSubSessionFuncMap_.erase(persistentId);
4637         }
4638         if (bindDialogTargetFuncMap_.find(persistentId) != bindDialogTargetFuncMap_.end()) {
4639             bindDialogTargetFuncMap_.erase(persistentId);
4640         }
4641         return WMError::WM_OK;
4642     }, __func__);
4643 }
4644 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)4645 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
4646 {
4647     if (!func) {
4648         TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4649     }
4650     statusBarEnabledChangeFunc_ = func;
4651 }
4652 
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)4653 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
4654     const ProcessGestureNavigationEnabledChangeFunc& func)
4655 {
4656     if (!func) {
4657         TLOGD(WmsLogTag::WMS_EVENT, "set func is null");
4658     }
4659     gestureNavigationEnabledChangeFunc_ = func;
4660 }
4661 
OnOutsideDownEvent(int32_t x,int32_t y)4662 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
4663 {
4664     TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
4665     if (outsideDownEventFunc_) {
4666         outsideDownEventFunc_(x, y);
4667     }
4668 }
4669 
GetDisplayGroupIdFromSceneSession(const sptr<SceneSession> & session,DisplayId & displayGroupId) const4670 WSError SceneSessionManager::GetDisplayGroupIdFromSceneSession(const sptr<SceneSession>& session,
4671     DisplayId& displayGroupId) const
4672 {
4673     if (session == nullptr) {
4674         return WSError::WS_ERROR_NULLPTR;
4675     }
4676     displayGroupId = GetDisplayGroupId(session->GetDisplayId());
4677     return WSError::WS_OK;
4678 }
4679 
IsSameDisplayGroupId(const sptr<SceneSession> & session,const DisplayId touchDisplayGroupId) const4680 bool SceneSessionManager::IsSameDisplayGroupId(const sptr<SceneSession>& session,
4681     const DisplayId touchDisplayGroupId) const
4682 {
4683     DisplayId displayGroupId = 0;
4684     if (GetDisplayGroupIdFromSceneSession(session, displayGroupId) != WSError::WS_OK) {
4685         TLOGD(WmsLogTag::WMS_EVENT, "session is null.");
4686         return false;
4687     }
4688     return displayGroupId == touchDisplayGroupId;
4689 }
4690 
NotifySessionTouchOutside(int32_t persistentId,DisplayId displayId)4691 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId, DisplayId displayId)
4692 {
4693     auto task = [this, persistentId, displayId]() {
4694         int32_t callingSessionId = INVALID_WINDOW_ID;
4695         auto sceneSession = GetSceneSession(persistentId);
4696         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
4697             callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
4698             TLOGND(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
4699                 persistentId, callingSessionId);
4700         }
4701         DisplayId touchDisplayGroupId = GetDisplayGroupId(displayId);
4702         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4703         for (const auto& [_, sceneSession] : sceneSessionMap_) {
4704             if (sceneSession == nullptr) {
4705                 continue;
4706             }
4707             if (!(sceneSession->IsVisible() ||
4708                   sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4709                   sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
4710                 continue;
4711             }
4712             if (!IsSameDisplayGroupId(sceneSession, touchDisplayGroupId)) {
4713                 continue;
4714             }
4715             auto sessionId = sceneSession->GetPersistentId();
4716             if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
4717                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
4718                 TLOGND(WmsLogTag::WMS_KEYBOARD, "id: %{public}d is not in touchOutsideListenerNodes, don't notify.",
4719                     sessionId);
4720                 continue;
4721             }
4722             if (sessionId == callingSessionId || sessionId == persistentId) {
4723                 TLOGND(WmsLogTag::WMS_KEYBOARD, "No need to notify touch window, id: %{public}d", sessionId);
4724                 continue;
4725             }
4726             sceneSession->NotifyTouchOutside();
4727         }
4728     };
4729 
4730     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
4731     return;
4732 }
4733 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)4734 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
4735 {
4736     TLOGD(WmsLogTag::WMS_EVENT, "in");
4737     outsideDownEventFunc_ = func;
4738 }
4739 
NotifyWatchGestureConsumeResult(int32_t keyCode,bool isConsumed)4740 WMError SceneSessionManager::NotifyWatchGestureConsumeResult(int32_t keyCode, bool isConsumed)
4741 {
4742     TLOGD(WmsLogTag::WMS_EVENT, "keyCode:%{public}d isConsumed:%{public}d", keyCode, isConsumed);
4743     if (onWatchGestureConsumeResultFunc_) {
4744         onWatchGestureConsumeResultFunc_(keyCode, isConsumed);
4745     } else {
4746         TLOGE(WmsLogTag::WMS_EVENT, "onWatchGestureConsumeResultFunc is null");
4747         return WMError::WM_ERROR_INVALID_PARAM;
4748     }
4749     return WMError::WM_OK;
4750 }
4751 
RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc && func)4752 void SceneSessionManager::RegisterWatchGestureConsumeResultCallback(NotifyWatchGestureConsumeResultFunc&& func)
4753 {
4754     TLOGD(WmsLogTag::WMS_EVENT, "in");
4755     onWatchGestureConsumeResultFunc_ = std::move(func);
4756 }
4757 
NotifyWatchFocusActiveChange(bool isActive)4758 WMError SceneSessionManager::NotifyWatchFocusActiveChange(bool isActive)
4759 {
4760     TLOGD(WmsLogTag::WMS_EVENT, "isActive:%{public}d", isActive);
4761     if (onWatchFocusActiveChangeFunc_) {
4762         onWatchFocusActiveChangeFunc_(isActive);
4763     } else {
4764         TLOGE(WmsLogTag::WMS_EVENT, "onWatchFocusActiveChangeFunc is null");
4765         return WMError::WM_ERROR_INVALID_PARAM;
4766     }
4767     return WMError::WM_OK;
4768 }
4769 
RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc && func)4770 void SceneSessionManager::RegisterWatchFocusActiveChangeCallback(NotifyWatchFocusActiveChangeFunc&& func)
4771 {
4772     TLOGD(WmsLogTag::WMS_EVENT, "in");
4773     onWatchFocusActiveChangeFunc_ = std::move(func);
4774 }
4775 
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)4776 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
4777 {
4778     for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
4779         if (iter->second != persistentId) {
4780             continue;
4781         }
4782         if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
4783             TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
4784         }
4785         remoteObjectMap_.erase(iter);
4786         break;
4787     }
4788 }
4789 
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)4790 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
4791 {
4792     auto sceneSession = GetSceneSession(persistentId);
4793     if (sceneSession == nullptr) {
4794         return WSError::WS_ERROR_NULLPTR;
4795     }
4796     auto ret = sceneSession->UpdateActiveStatus(false);
4797     RemoveSessionFromBlackList(sceneSession);
4798     WindowDestroyNotifyVisibility(sceneSession);
4799     auto windowType = sceneSession->GetWindowType();
4800     if (windowType == WindowType::WINDOW_TYPE_DIALOG) {
4801         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4802         if (parentSession == nullptr) {
4803             TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
4804         } else {
4805             parentSession->RemoveDialogToParentSession(sceneSession);
4806             parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4807         }
4808     } else if (windowType == WindowType::WINDOW_TYPE_TOAST) {
4809         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4810         if (parentSession != nullptr) {
4811             TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
4812             parentSession->RemoveToastSession(persistentId);
4813         } else {
4814             TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
4815         }
4816     } else if (windowType == WindowType::WINDOW_TYPE_FLOAT) {
4817         DestroySubSession(sceneSession);
4818     }
4819     ret = sceneSession->Disconnect();
4820     sceneSession->ClearSpecificSessionCbMap();
4821     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
4822         DestroySubSession(sceneSession);
4823         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
4824         if (parentSession != nullptr) {
4825             TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
4826             parentSession->RemoveSubSession(sceneSession->GetPersistentId());
4827             parentSession->UnregisterNotifySurfaceBoundsChangeFunc(persistentId);
4828         } else {
4829             TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
4830         }
4831         DestroyUIServiceExtensionSubWindow(sceneSession);
4832     }
4833     {
4834         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4835         EraseSceneSessionAndMarkDirtyLocked(persistentId);
4836         systemTopSceneSessionMap_.erase(persistentId);
4837         nonSystemFloatSceneSessionMap_.erase(persistentId);
4838         UnregisterSpecificSessionCreateListener(persistentId);
4839     }
4840     ClearSpecificSessionRemoteObjectMap(persistentId);
4841     TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
4842     return ret;
4843 }
4844 
DestroyAndDisconnectSpecificSession(const int32_t persistentId)4845 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
4846 {
4847     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4848     auto task = [this, persistentId, callingPid]() {
4849         TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4850         auto sceneSession = GetSceneSession(persistentId);
4851         if (sceneSession == nullptr) {
4852             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4853             return WSError::WS_ERROR_NULLPTR;
4854         }
4855 
4856         if (callingPid != sceneSession->GetCallingPid()) {
4857             TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4858             return WSError::WS_ERROR_INVALID_PERMISSION;
4859         }
4860         return DestroyAndDisconnectSpecificSessionInner(persistentId);
4861     };
4862 
4863     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4864 }
4865 
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)4866 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
4867     const sptr<IRemoteObject>& callback)
4868 {
4869     if (callback == nullptr) {
4870         return WSError::WS_ERROR_NULLPTR;
4871     }
4872     const auto callingPid = IPCSkeleton::GetCallingRealPid();
4873     auto task = [this, persistentId, callingPid, callback]() {
4874         TLOGNI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
4875         auto sceneSession = GetSceneSession(persistentId);
4876         if (sceneSession == nullptr) {
4877             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
4878             return WSError::WS_ERROR_NULLPTR;
4879         }
4880 
4881         if (callingPid != sceneSession->GetCallingPid()) {
4882             TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
4883             return WSError::WS_ERROR_INVALID_PERMISSION;
4884         }
4885         sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
4886         return DestroyAndDisconnectSpecificSessionInner(persistentId);
4887     };
4888 
4889     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
4890 }
4891 
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)4892 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
4893 {
4894     if (!sceneSession) {
4895         TLOGE(WmsLogTag::WMS_SUB, "sceneSession is null");
4896         return;
4897     }
4898     auto sessionProperty = sceneSession->GetSessionProperty();
4899     if (sessionProperty->GetIsUIExtFirstSubWindow() &&
4900         !sessionProperty->GetIsUIExtensionAbilityProcess()) {
4901         sceneSession->NotifyDestroy();
4902         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
4903             TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
4904         TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
4905             sceneSession->GetPersistentId(), errCode);
4906     }
4907 }
4908 
GetWindowSceneConfig() const4909 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
4910 {
4911     return appWindowSceneConfig_;
4912 }
4913 
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)4914 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
4915 {
4916     taskScheduler_->PostAsyncTask([this, config] {
4917         TLOGNI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
4918         rotateAnimationConfig_.duration_ = config.duration_;
4919     }, __func__);
4920 }
4921 
ProcessBackEvent()4922 WSError SceneSessionManager::ProcessBackEvent()
4923 {
4924     taskScheduler_->PostAsyncTask([this]() {
4925         auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
4926         if (focusGroup == nullptr) {
4927             TLOGNE(WmsLogTag::WMS_MAIN, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
4928             return WSError::WS_ERROR_NULLPTR;
4929         }
4930         auto focusedSessionId = focusGroup->GetFocusedSessionId();
4931         auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
4932         auto session = GetSceneSession(focusedSessionId);
4933         if (!session) {
4934             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId);
4935             return WSError::WS_ERROR_INVALID_SESSION;
4936         }
4937         TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
4938             focusedSessionId, needBlockNotifyFocusStatusUntilForeground);
4939         if (needBlockNotifyFocusStatusUntilForeground ||
4940             (!session->IsSessionValid() && !session->IsSystemSession())) {
4941             TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
4942             if (session->GetSessionInfo().abilityInfo != nullptr &&
4943                 session->GetSessionInfo().abilityInfo->unclearableMission) {
4944                 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
4945                 return WSError::WS_OK;
4946             }
4947             session->RequestSessionBack(true);
4948             return WSError::WS_OK;
4949         }
4950         if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
4951             rootSceneProcessBackEventFunc_();
4952         } else {
4953             session->ProcessBackEvent();
4954         }
4955         return WSError::WS_OK;
4956     }, __func__);
4957     return WSError::WS_OK;
4958 }
4959 
InitUserInfo(int32_t userId,std::string & fileDir)4960 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
4961 {
4962     if (userId == DEFAULT_USERID || fileDir.empty()) {
4963         TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
4964         return WSError::WS_DO_NOTHING;
4965     }
4966     TLOGI(WmsLogTag::WMS_MAIN, "userId: %{public}d, path: %{public}s", userId, fileDir.c_str());
4967     InitStartingWindowRdb(fileDir + "/StartingWindowRdb/");
4968     return taskScheduler_->PostSyncTask([this, userId, &fileDir]() {
4969         if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
4970             TLOGND(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
4971         }
4972         if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
4973             TLOGND(WmsLogTag::WMS_MAIN, "Create icon directory failed");
4974         }
4975         currentUserId_ = userId;
4976         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
4977         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
4978             MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
4979         }
4980         AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
4981         RegisterSecSurfaceInfoListener();
4982         RegisterConstrainedModalUIExtInfoListener();
4983         return WSError::WS_OK;
4984     }, __func__);
4985 }
4986 
IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession> & sceneSession,int32_t pid)4987 bool SceneSessionManager::IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)
4988 {
4989     auto sessionState = sceneSession->GetSessionState();
4990     auto isInvalidMainSession = !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
4991                                 sessionState == SessionState::STATE_DISCONNECT ||
4992                                 sessionState == SessionState::STATE_END;
4993     if (isInvalidMainSession) {
4994         TLOGD(WmsLogTag::WMS_MULTI_USER, "persistentId: %{public}d, type: %{public}d, state: %{public}d",
4995             sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState());
4996     }
4997     return sceneSession->GetCallingPid() != pid && IsPcSceneSessionLifecycle(sceneSession) && !isInvalidMainSession;
4998 }
4999 
StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession> & sceneSession,bool isUserActive)5000 WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)
5001 {
5002     auto persistentId = sceneSession->GetPersistentId();
5003     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
5004     if (!isUserActive) {
5005         TLOGI(WmsLogTag::WMS_MULTI_USER,
5006             "MinimizeUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
5007             sceneSession->GetWindowType(), sceneSession->GetSessionState());
5008         bool isFromUser = false;
5009         TLOGNI(WmsLogTag::WMS_LIFE, "MinimizeUIAbilityBySCB, Notify scene session id: %{public}d paused", persistentId);
5010         sceneSession->UpdateLifecyclePausedInner();
5011         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(
5012             abilitySessionInfo, isFromUser, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
5013         if (errCode == ERR_OK) {
5014             sceneSession->SetMinimizedFlagByUserSwitch(true);
5015         } else {
5016             TLOGE(WmsLogTag::WMS_MULTI_USER, "minimize failed! errCode: %{public}d", errCode);
5017         }
5018     } else if (sceneSession->IsMinimizedByUserSwitch()) {
5019         TLOGI(WmsLogTag::WMS_MULTI_USER,
5020             "StartUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
5021             sceneSession->GetWindowType(), sceneSession->GetSessionState());
5022         sceneSession->SetMinimizedFlagByUserSwitch(false);
5023         bool isColdStart = false;
5024         abilitySessionInfo->isNewWant = false;
5025         int32_t errCode = StartUIAbilityBySCBTimeoutCheck(sceneSession,
5026             abilitySessionInfo, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH), isColdStart);
5027         if (errCode != ERR_OK) {
5028             TLOGE(WmsLogTag::WMS_MULTI_USER, "start failed! errCode: %{public}d", errCode);
5029             ExceptionInfo exceptionInfo;
5030             exceptionInfo.needRemoveSession = true;
5031             sceneSession->NotifySessionExceptionInner(abilitySessionInfo, exceptionInfo, false, true);
5032             if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
5033                 startUIAbilityErrorFunc_(
5034                     static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
5035             }
5036         }
5037     }
5038     return WSError::WS_OK;
5039 }
5040 
ProcessUIAbilityOnUserSwitch(bool isUserActive)5041 void SceneSessionManager::ProcessUIAbilityOnUserSwitch(bool isUserActive)
5042 {
5043     int32_t pid = GetPid();
5044     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5045     for (const auto& [_, sceneSession] : sceneSessionMap_) {
5046         if (sceneSession == nullptr) {
5047             TLOGE(WmsLogTag::WMS_MULTI_USER, "session is null");
5048             continue;
5049         }
5050         // Change app life cycle in pc when user switch, do app freeze or unfreeze
5051         if (IsNeedChangeLifeCycleOnUserSwitch(sceneSession, pid)) {
5052             StartOrMinimizeUIAbilityBySCB(sceneSession, isUserActive);
5053         }
5054     }
5055 }
5056 
HandleUserSwitching(bool isUserActive)5057 void SceneSessionManager::HandleUserSwitching(bool isUserActive)
5058 {
5059     // A brief screen freeze may occur when handling a switching event.
5060     // Record the duration and report it to HiSysEvent for troubleshooting.
5061     UserSwitchReporter reporter(isUserActive);
5062 
5063     isUserBackground_ = !isUserActive;
5064     SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
5065     if (isUserActive) { // switch to current user
5066         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
5067         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
5068             MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
5069         }
5070         AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
5071         // notify screenSessionManager to recover current user
5072         ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
5073         FlushWindowInfoToMMI(true);
5074         NotifyAllAccessibilityInfo();
5075         rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
5076         UpdatePrivateStateAndNotifyForAllScreens();
5077     } else { // switch to another user
5078         SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
5079         // minimized UI abilities when the user is switching and inactive
5080         ProcessUIAbilityOnUserSwitch(isUserActive);
5081     }
5082 }
5083 
HandleUserSwitched(bool isUserActive)5084 void SceneSessionManager::HandleUserSwitched(bool isUserActive)
5085 {
5086     if (isUserActive) {
5087         // start UI abilities only after the user has switched and become active
5088         ProcessUIAbilityOnUserSwitch(isUserActive);
5089     } else {
5090         rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
5091     }
5092 }
5093 
HandleUserSwitch(const UserSwitchEventType type,const bool isUserActive)5094 void SceneSessionManager::HandleUserSwitch(const UserSwitchEventType type, const bool isUserActive)
5095 {
5096     if (type == UserSwitchEventType::SWITCHING && !isUserActive) {
5097         ScreenSessionManagerClient::GetInstance().DisconnectAllExternalScreen();
5098     }
5099 
5100     taskScheduler_->PostSyncTask([this, type, isUserActive, where = __func__] {
5101         TLOGNI(WmsLogTag::WMS_MULTI_USER,
5102                "%{public}s: currentUserId: %{public}d, switchEventType: %{public}u, isUserActive: %{public}u",
5103                where, currentUserId_.load(), type, isUserActive);
5104         switch (type) {
5105             case UserSwitchEventType::SWITCHING: {
5106                 HandleUserSwitching(isUserActive);
5107                 break;
5108             }
5109             case UserSwitchEventType::SWITCHED: {
5110                 HandleUserSwitched(isUserActive);
5111                 break;
5112             }
5113             default: {
5114                 TLOGNW(WmsLogTag::WMS_MULTI_USER, "%{public}s: Invalid switchEventType: %{public}u", where, type);
5115                 break;
5116             }
5117         }
5118         return WSError::WS_OK;
5119     }, __func__);
5120 }
5121 
GetBundleManager()5122 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
5123 {
5124     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
5125     if (systemAbilityMgr == nullptr) {
5126         TLOGE(WmsLogTag::DEFAULT, "Failed to get SystemAbilityManager.");
5127         return nullptr;
5128     }
5129     auto bmsProxy = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
5130     if (bmsProxy == nullptr) {
5131         TLOGE(WmsLogTag::DEFAULT, "Failed to get BundleManagerService.");
5132         return nullptr;
5133     }
5134     return iface_cast<AppExecFwk::IBundleMgr>(bmsProxy);
5135 }
5136 
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)5137 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
5138     const AppExecFwk::AbilityInfo& abilityInfo)
5139 {
5140     auto context = rootSceneContextWeak_.lock();
5141     if (!context) {
5142         TLOGE(WmsLogTag::DEFAULT, "context is nullptr.");
5143         return nullptr;
5144     }
5145     auto resourceMgr = context->GetResourceManager();
5146     if (!resourceMgr) {
5147         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
5148         return nullptr;
5149     }
5150     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
5151     if (!resConfig) {
5152         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
5153         return nullptr;
5154     }
5155     resourceMgr->GetResConfig(*resConfig);
5156     resourceMgr = Global::Resource::CreateResourceManager(
5157         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
5158     if (!resourceMgr) {
5159         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
5160         return nullptr;
5161     }
5162     resourceMgr->UpdateResConfig(*resConfig);
5163 
5164     std::string loadPath;
5165     if (!abilityInfo.hapPath.empty()) { // zipped hap
5166         loadPath = abilityInfo.hapPath;
5167     } else {
5168         loadPath = abilityInfo.resourcePath;
5169     }
5170 
5171     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA |
5172         Global::Resource::SELECT_PROF)) {
5173         TLOGW(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
5174     }
5175     return resourceMgr;
5176 }
5177 
GetPathInfoFromResource(const std::shared_ptr<Global::Resource::ResourceManager> resourceMgr,bool hapPathEmpty,uint32_t resourceId,std::string & path)5178 bool SceneSessionManager::GetPathInfoFromResource(const std::shared_ptr<Global::Resource::ResourceManager> resourceMgr,
5179     bool hapPathEmpty, uint32_t resourceId, std::string& path)
5180 {
5181     if (resourceId == 0) {
5182         TLOGD(WmsLogTag::WMS_PATTERN, "resource invalid:%{public}u", resourceId);
5183         return false;
5184     }
5185     if (resourceMgr->GetMediaById(resourceId, path) != Global::Resource::RState::SUCCESS) {
5186         TLOGE(WmsLogTag::WMS_PATTERN, "failed id:%{public}u", resourceId);
5187         return false;
5188     }
5189     if (!hapPathEmpty) {
5190         auto pos = path.find_last_of('.');
5191         if (pos == std::string::npos) {
5192             TLOGE(WmsLogTag::WMS_PATTERN, "Format error, path %{private}s", path.c_str());
5193             return false;
5194         }
5195         path = "resource:///" + std::to_string(resourceId) + path.substr(pos);
5196     }
5197     return true;
5198 }
5199 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,StartingWindowInfo & startingWindowInfo)5200 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
5201     StartingWindowInfo& startingWindowInfo)
5202 {
5203     const std::map<std::string, std::string> START_WINDOW_KEY_AND_DEFAULT_MAP = {
5204         {STARTWINDOW_TYPE, "REQUIRED_SHOW"},
5205     };
5206 
5207     auto resourceMgr = GetResourceManager(abilityInfo);
5208     if (!resourceMgr) {
5209         TLOGE(WmsLogTag::WMS_PATTERN, "resourceMgr is nullptr.");
5210         return false;
5211     }
5212     bool hapPathEmpty = abilityInfo.hapPath.empty();
5213     if (hapPathEmpty) {
5214         TLOGD(WmsLogTag::WMS_PATTERN, "hapPath empty:%{public}s", abilityInfo.bundleName.c_str());
5215     }
5216 
5217     const auto startWindowType = START_WINDOW_KEY_AND_DEFAULT_MAP.find(STARTWINDOW_TYPE);
5218     if (startWindowType != START_WINDOW_KEY_AND_DEFAULT_MAP.end()) {
5219         startingWindowInfo.startWindowType_ = startingWindowRdbMgr_->GetStartWindowValFromProfile(
5220             abilityInfo, resourceMgr, startWindowType->first, startWindowType->second);
5221     }
5222 
5223     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId,
5224             startingWindowInfo.backgroundColorEarlyVersion_) != Global::Resource::RState::SUCCESS ||
5225         !GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5226             abilityInfo.startWindowIconId, startingWindowInfo.iconPathEarlyVersion_)) {
5227         if (!emptyStartupResource_.count(abilityInfo.bundleName)) {
5228             emptyStartupResource_.insert(abilityInfo.bundleName);
5229             TLOGE(WmsLogTag::WMS_PATTERN, "failed:%{public}s.", abilityInfo.bundleName.c_str());
5230         }
5231         return false;
5232     }
5233     // check start_window.json enabled by required field
5234     startingWindowInfo.configFileEnabled_ = abilityInfo.startWindowResource.startWindowBackgroundColorId != 0;
5235     if (!startingWindowInfo.configFileEnabled_) {
5236         return true;
5237     }
5238     if (resourceMgr->GetColorById(abilityInfo.startWindowResource.startWindowBackgroundColorId,
5239             startingWindowInfo.backgroundColor_) != Global::Resource::RState::SUCCESS) {
5240         TLOGE(WmsLogTag::WMS_PATTERN, "failed:%{public}s.", abilityInfo.bundleName.c_str());
5241         return false;
5242     }
5243     auto res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5244         abilityInfo.startWindowResource.startWindowAppIconId, startingWindowInfo.iconPath_);
5245     res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5246         abilityInfo.startWindowResource.startWindowIllustrationId, startingWindowInfo.illustrationPath_) && res;
5247     res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5248         abilityInfo.startWindowResource.startWindowBackgroundImageId, startingWindowInfo.backgroundImagePath_) && res;
5249     res = GetPathInfoFromResource(resourceMgr, hapPathEmpty,
5250         abilityInfo.startWindowResource.startWindowBrandingImageId, startingWindowInfo.brandingPath_) && res;
5251     TLOGD(WmsLogTag::WMS_PATTERN, "all image configured:%{public}s, %{public}d", abilityInfo.bundleName.c_str(), res);
5252     startingWindowInfo.backgroundImageFit_ = abilityInfo.startWindowResource.startWindowBackgroundImageFit;
5253     return true;
5254 }
5255 
GetIsDarkFromConfiguration()5256 bool SceneSessionManager::GetIsDarkFromConfiguration()
5257 {
5258     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
5259     if (appContext == nullptr) {
5260         TLOGE(WmsLogTag::WMS_PATTERN, "app context is nullptr");
5261         return false;
5262     }
5263     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
5264     if (config == nullptr) {
5265         TLOGE(WmsLogTag::WMS_PATTERN, "app configuration is nullptr");
5266         return false;
5267     }
5268     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
5269     TLOGI(WmsLogTag::WMS_PATTERN, "colorMode: %{public}s", colorMode.c_str());
5270     return (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
5271 }
5272 
GetBundleStartingWindowInfos(bool isDark,const AppExecFwk::BundleInfo & bundleInfo,std::vector<std::pair<StartingWindowRdbItemKey,StartingWindowInfo>> & outValues)5273 void SceneSessionManager::GetBundleStartingWindowInfos(bool isDark, const AppExecFwk::BundleInfo& bundleInfo,
5274     std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>>& outValues)
5275 {
5276     for (const auto& moduleInfo : bundleInfo.hapModuleInfos) {
5277         for (const auto& abilityInfo : moduleInfo.abilityInfos) {
5278             StartingWindowRdbItemKey itemKey = {
5279                 .bundleName = abilityInfo.bundleName,
5280                 .moduleName = abilityInfo.moduleName,
5281                 .abilityName = abilityInfo.name,
5282                 .darkMode = isDark,
5283             };
5284             StartingWindowInfo startingWindowInfo;
5285             if (!GetStartupPageFromResource(abilityInfo, startingWindowInfo)) {
5286                 continue;
5287             }
5288             outValues.emplace_back(std::make_pair(itemKey, startingWindowInfo));
5289         }
5290     }
5291 }
5292 
GetIconFromDesk(const SessionInfo & sessionInfo,std::string & startupPagePath) const5293 bool SceneSessionManager::GetIconFromDesk(const SessionInfo& sessionInfo, std::string& startupPagePath) const
5294 {
5295     auto& want = sessionInfo.want;
5296     if (want == nullptr) {
5297         TLOGI(WmsLogTag::WMS_PATTERN, "want is nullPtr");
5298         return false;
5299     }
5300     startupPagePath = want->GetStringParam("realAppIcon");
5301     if (startupPagePath.empty()) {
5302         return false;
5303     }
5304     return true;
5305 }
5306 
InitStartingWindowRdb(const std::string & rdbPath)5307 void SceneSessionManager::InitStartingWindowRdb(const std::string& rdbPath)
5308 {
5309     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:InitStartingWindowRdb");
5310     WmsRdbConfig config;
5311     config.dbPath = rdbPath;
5312     if (mkdir(rdbPath.c_str(), S_IRWXU)) {
5313         TLOGW(WmsLogTag::WMS_PATTERN, "mkdir failed or already exists");
5314     }
5315     startingWindowRdbMgr_ = std::make_unique<StartingWindowRdbManager>(config);
5316     if (startingWindowRdbMgr_ == nullptr) {
5317         TLOGE(WmsLogTag::WMS_PATTERN, "create rdb manager fail");
5318         return;
5319     }
5320     if (!startingWindowRdbMgr_->Init()) {
5321         TLOGE(WmsLogTag::WMS_PATTERN, "init fail %{private}s", config.dbPath.c_str());
5322         return;
5323     }
5324     bool deleteAllDataRes = startingWindowRdbMgr_->DeleteAllData();
5325     TLOGI(WmsLogTag::WMS_PATTERN, "delete all data res: %{public}d", deleteAllDataRes);
5326 }
5327 
UpdateAllStartingWindowRdb()5328 void SceneSessionManager::UpdateAllStartingWindowRdb()
5329 {
5330     const char* const where = __func__;
5331     auto loadTask = [this, where]() {
5332         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:UpdateAllStartingWindowRdb");
5333         if (bundleMgr_ == nullptr) {
5334             TLOGNE(WmsLogTag::WMS_PATTERN, "bundleMgr is nullptr");
5335             return;
5336         }
5337         std::vector<AppExecFwk::BundleInfo> bundleInfos;
5338         int32_t ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(
5339             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) |
5340             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
5341             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
5342             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_ONLY_WITH_LAUNCHER_ABILITY),
5343             bundleInfos, currentUserId_));
5344         if (ret != 0) {
5345             TLOGNE(WmsLogTag::WMS_PATTERN, "GetBundleInfosV9 error:%{public}d", ret);
5346             return;
5347         }
5348         std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>> inputValues;
5349         bool isDark = GetIsDarkFromConfiguration();
5350         for (const auto& bundleInfo : bundleInfos) {
5351             GetBundleStartingWindowInfos(isDark, bundleInfo, inputValues);
5352         }
5353         int64_t outInsertNum = -1;
5354         auto batchInsertRes = startingWindowRdbMgr_->BatchInsert(outInsertNum, inputValues);
5355         TLOGNI(WmsLogTag::WMS_PATTERN, "res: %{public}d, bundles: %{public}zu, insert: %{public}" PRId64,
5356             batchInsertRes, bundleInfos.size(), outInsertNum);
5357         startingWindowRdbMgr_->ClearRdbStore();
5358         };
5359     ffrtQueueHelper_->SubmitTask(loadTask);
5360 }
5361 
GetStartupPage(const SessionInfo & sessionInfo,StartingWindowInfo & startingWindowInfo)5362 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, StartingWindowInfo& startingWindowInfo)
5363 {
5364     if (GetIconFromDesk(sessionInfo, startingWindowInfo.iconPathEarlyVersion_)) {
5365         TLOGI(WmsLogTag::WMS_PATTERN, "get icon from desk success");
5366         return;
5367     }
5368     if (!bundleMgr_) {
5369         TLOGE(WmsLogTag::WMS_PATTERN, "bundleMgr_ is nullptr.");
5370         return;
5371     }
5372     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
5373     if (GetStartingWindowInfoFromCache(sessionInfo, startingWindowInfo)) {
5374         return;
5375     }
5376     if (GetStartingWindowInfoFromRdb(sessionInfo, startingWindowInfo)) {
5377         CacheStartingWindowInfo(
5378             sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5379         uint32_t updateRes = UpdateCachedColorToAppSet(
5380             sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5381         TLOGI(WmsLogTag::WMS_PATTERN, "updateRes %{public}u, %{public}x",
5382             updateRes, startingWindowInfo.backgroundColor_);
5383         return;
5384     }
5385     AAFwk::Want want;
5386     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
5387     AppExecFwk::AbilityInfo abilityInfo;
5388     if (!bundleMgr_->QueryAbilityInfo(
5389         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
5390         TLOGE(WmsLogTag::WMS_PATTERN, "Get ability info from BMS failed!");
5391         return;
5392     }
5393     if (GetStartupPageFromResource(abilityInfo, startingWindowInfo)) {
5394         CacheStartingWindowInfo(
5395             sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5396         if (startingWindowRdbMgr_ != nullptr) {
5397             StartingWindowRdbItemKey itemKey = {
5398                 .bundleName = sessionInfo.bundleName_,
5399                 .moduleName = sessionInfo.moduleName_,
5400                 .abilityName = sessionInfo.abilityName_,
5401                 .darkMode = GetIsDarkFromConfiguration(),
5402             };
5403             if (!startingWindowRdbMgr_->InsertData(itemKey, startingWindowInfo)) {
5404                 TLOGW(WmsLogTag::WMS_PATTERN, "rdb insert faild");
5405             }
5406         }
5407         uint32_t updateRes = UpdateCachedColorToAppSet(
5408             sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_, startingWindowInfo);
5409         TLOGI(WmsLogTag::WMS_PATTERN, "updateRes %{public}u, %{public}x",
5410             updateRes, startingWindowInfo.backgroundColor_);
5411     }
5412     TLOGW(WmsLogTag::WMS_PATTERN, "%{public}d, %{public}x", startingWindowInfo.configFileEnabled_,
5413         startingWindowInfo.configFileEnabled_ ? startingWindowInfo.backgroundColor_ :
5414                                                 startingWindowInfo.backgroundColorEarlyVersion_);
5415 }
5416 
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,StartingWindowInfo & startingWindowInfo)5417 bool SceneSessionManager::GetStartingWindowInfoFromCache(
5418     const SessionInfo& sessionInfo, StartingWindowInfo& startingWindowInfo)
5419 {
5420     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
5421     std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5422     auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
5423     if (iter == startingWindowMap_.end()) {
5424         return false;
5425     }
5426     auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
5427     const auto& infoMap = iter->second;
5428     auto infoMapIter = infoMap.find(key);
5429     if (infoMapIter == infoMap.end()) {
5430         return false;
5431     }
5432     startingWindowInfo = infoMapIter->second;
5433     TLOGW(WmsLogTag::WMS_PATTERN, "%{public}x, %{public}s, %{public}x, %{public}s",
5434         startingWindowInfo.backgroundColorEarlyVersion_, startingWindowInfo.iconPathEarlyVersion_.c_str(),
5435         startingWindowInfo.backgroundColor_, startingWindowInfo.iconPath_.c_str());
5436     return true;
5437 }
5438 
GetStartingWindowInfoFromRdb(const SessionInfo & sessionInfo,StartingWindowInfo & startingWindowInfo)5439 bool SceneSessionManager::GetStartingWindowInfoFromRdb(
5440     const SessionInfo& sessionInfo, StartingWindowInfo& startingWindowInfo)
5441 {
5442     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromRdb");
5443     if (startingWindowRdbMgr_ == nullptr) {
5444         TLOGE(WmsLogTag::WMS_PATTERN, "rdb is nullptr");
5445         return false;
5446     }
5447     StartingWindowRdbItemKey itemKey = {
5448         .bundleName = sessionInfo.bundleName_,
5449         .moduleName = sessionInfo.moduleName_,
5450         .abilityName = sessionInfo.abilityName_,
5451         .darkMode = GetIsDarkFromConfiguration(),
5452     };
5453     bool res = startingWindowRdbMgr_->QueryData(itemKey, startingWindowInfo);
5454     TLOGW(WmsLogTag::WMS_PATTERN, "%{public}x, %{public}s, %{public}x, %{public}s, %{public}d",
5455         startingWindowInfo.backgroundColorEarlyVersion_, startingWindowInfo.iconPathEarlyVersion_.c_str(),
5456         startingWindowInfo.backgroundColor_, startingWindowInfo.iconPath_.c_str(), res);
5457     return res;
5458 }
5459 
UpdateCachedColorToAppSet(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,StartingWindowInfo & info)5460 uint32_t SceneSessionManager::UpdateCachedColorToAppSet(const std::string& bundleName, const std::string& moduleName,
5461     const std::string& abilityName, StartingWindowInfo& info)
5462 {
5463     auto key = moduleName + abilityName;
5464     uint32_t color = 0;
5465     std::unordered_map<std::string, std::unordered_map<std::string, uint32_t>> colorFromAppMap;
5466     {
5467         std::shared_lock<std::shared_mutex> lock(startingWindowColorFromAppMapMutex_);
5468         colorFromAppMap = startingWindowColorFromAppMap_;
5469     }
5470     auto colorMapIter = colorFromAppMap.find(bundleName);
5471     if (colorMapIter == colorFromAppMap.end()) {
5472         return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::COLOR_MAP_BUNDLE_NOT_FOUND);
5473     }
5474     auto& colorMap = colorMapIter->second;
5475     auto colorIter = colorMap.find(key);
5476     if (colorIter == colorMap.end()) {
5477         return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::COLOR_MAP_KEY_PAIR_NOT_FOUND);
5478     }
5479     color = colorIter->second;
5480     info.backgroundColor_ = color;
5481     info.backgroundColorEarlyVersion_ = color;
5482     {
5483         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5484         auto iter = startingWindowMap_.find(bundleName);
5485         if (iter == startingWindowMap_.end()) {
5486             return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::INFO_MAP_BUNDLE_NOT_FOUND);
5487         }
5488         auto& infoMap = iter->second;
5489         auto infoIter = infoMap.find(key);
5490         if (infoIter == infoMap.end()) {
5491             return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::INFO_MAP_BUNDLE_NOT_FOUND);
5492         }
5493         infoIter->second.backgroundColorEarlyVersion_ = color;
5494         infoIter->second.backgroundColor_ = color;
5495     }
5496     return static_cast<uint32_t>(UpdateStartingWindowColorCacheResult::SUCCESS);
5497 }
5498 
CacheStartingWindowInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const StartingWindowInfo & startingWindowInfo)5499 void SceneSessionManager::CacheStartingWindowInfo(const std::string& bundleName, const std::string& moduleName,
5500     const std::string& abilityName, const StartingWindowInfo& startingWindowInfo)
5501 {
5502     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
5503     auto key = moduleName + abilityName;
5504     std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5505     auto iter = startingWindowMap_.find(bundleName);
5506     if (iter != startingWindowMap_.end()) {
5507         auto& infoMap = iter->second;
5508         infoMap.emplace(key, startingWindowInfo);
5509         return;
5510     }
5511     if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
5512         startingWindowMap_.erase(startingWindowMap_.begin());
5513     }
5514     std::map<std::string, StartingWindowInfo> infoMap({{ key, startingWindowInfo }});
5515     startingWindowMap_.emplace(bundleName, infoMap);
5516 }
5517 
GetPreLoadStartingWindow(const SessionInfo & sessionInfo)5518 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetPreLoadStartingWindow(const SessionInfo& sessionInfo)
5519 {
5520     std::unordered_map<std::string, std::shared_ptr<Media::PixelMap>> preLoadMap;
5521     {
5522         std::shared_lock<std::shared_mutex> lock(preLoadstartingWindowMapMutex_);
5523         preLoadMap = preLoadStartingWindowMap_;
5524     }
5525     std::string key = sessionInfo.bundleName_ + '_' + sessionInfo.moduleName_ + '_' +sessionInfo.abilityName_;
5526     auto iter = preLoadMap.find(key);
5527     if (iter == preLoadMap.end()) {
5528         TLOGI(WmsLogTag::WMS_PATTERN, "%{public}s not found", key.c_str());
5529         return nullptr;
5530     }
5531     return iter->second;
5532 }
5533 
RemovePreLoadStartingWindowFromMap(const SessionInfo & sessionInfo)5534 void SceneSessionManager::RemovePreLoadStartingWindowFromMap(const SessionInfo& sessionInfo)
5535 {
5536     std::string key = sessionInfo.bundleName_ + '_' + sessionInfo.moduleName_ + '_' +sessionInfo.abilityName_;
5537     std::unique_lock<std::shared_mutex> lock(preLoadstartingWindowMapMutex_);
5538     auto iter = preLoadStartingWindowMap_.find(key);
5539     if (iter != preLoadStartingWindowMap_.end()) {
5540         preLoadStartingWindowMap_.erase(iter);
5541         TLOGI(WmsLogTag::WMS_PATTERN, "%{public}s", key.c_str());
5542     }
5543 }
5544 
PreLoadStartingWindow(sptr<SceneSession> sceneSession)5545 void SceneSessionManager::PreLoadStartingWindow(sptr<SceneSession> sceneSession)
5546 {
5547     const char* const where = __func__;
5548     auto loadTask = [this, weakSceneSession = wptr(sceneSession), where]() {
5549         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:PreLoadStartingWindow");
5550         sptr<SceneSession> sceneSession = weakSceneSession.promote();
5551         if (sceneSession == nullptr) {
5552             TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s session is nullptr", where);
5553             return;
5554         }
5555         auto sessionInfo = sceneSession->GetSessionInfo();
5556         if (!SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
5557             TLOGND(WmsLogTag::WMS_PATTERN, "%{public}s id: %{public}d is not main window",
5558                 where, sceneSession->GetPersistentId());
5559             return;
5560         }
5561         if (sessionInfo.isPersistentRecover_) {
5562             TLOGNI(WmsLogTag::WMS_PATTERN, "%{public}s skip id: %{public}d for recover",
5563                 where, sceneSession->GetPersistentId());
5564             return;
5565         }
5566         StartingWindowInfo startingWindowInfo;
5567         GetStartupPage(sessionInfo, startingWindowInfo);
5568         uint32_t resId = 0;
5569         if (!CheckAndGetPreLoadResourceId(startingWindowInfo, resId)) {
5570             TLOGND(WmsLogTag::WMS_PATTERN, "%{public}s check no need preLoad", where);
5571             return;
5572         }
5573         if (sessionInfo.abilityInfo == nullptr) {
5574             TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s id: %{public}d abilityInfo is nullptr",
5575                 where, sceneSession->GetPersistentId());
5576             return;
5577         }
5578         auto pixelMap = GetPixelMap(resId, sessionInfo.abilityInfo);
5579         if (pixelMap == nullptr) {
5580             TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s pixelMap is nullptr", where);
5581             return;
5582         }
5583         std::string key = sessionInfo.bundleName_ + '_' + sessionInfo.moduleName_ + '_' +sessionInfo.abilityName_;
5584         {
5585             std::unique_lock<std::shared_mutex> lock(preLoadstartingWindowMapMutex_);
5586             preLoadStartingWindowMap_[key] = pixelMap;
5587         }
5588         sceneSession->NotifyPreLoadStartingWindowFinished();
5589     };
5590     ffrtQueueHelper_->SubmitTask(loadTask);
5591     if (needUpdateRdb_) {
5592         UpdateAllStartingWindowRdb();
5593         needUpdateRdb_ = false;
5594     }
5595 }
5596 
CheckAndGetPreLoadResourceId(const StartingWindowInfo & startingWindowInfo,uint32_t & resId)5597 bool SceneSessionManager::CheckAndGetPreLoadResourceId(const StartingWindowInfo& startingWindowInfo, uint32_t& resId)
5598 {
5599     if (startingWindowInfo.configFileEnabled_) {
5600         TLOGD(WmsLogTag::WMS_PATTERN, "config file enabled");
5601         return false;
5602     }
5603     const auto& iconPath= startingWindowInfo.iconPathEarlyVersion_;
5604     auto pos = iconPath.find_last_of('.');
5605     constexpr uint32_t RESOURCE_PATH_HEAD_LENGTH = 12;
5606     if (pos == std::string::npos || pos <= RESOURCE_PATH_HEAD_LENGTH) {
5607         TLOGE(WmsLogTag::WMS_PATTERN, "format error: %{private}s", iconPath.c_str());
5608         return false;
5609     }
5610     const auto& extName = iconPath.substr(pos);
5611     if (extName != ".png" && extName != ".jpg") {
5612         TLOGI(WmsLogTag::WMS_PATTERN, "format not need preLoad: %{private}s", iconPath.c_str());
5613         return false;
5614     }
5615     const auto& resIdStr = iconPath.substr(RESOURCE_PATH_HEAD_LENGTH, pos - RESOURCE_PATH_HEAD_LENGTH);
5616     if (!WindowHelper::IsNumber(resIdStr)) {
5617         TLOGE(WmsLogTag::WMS_PATTERN, "number format error: %{public}s", resIdStr.c_str());
5618         return false;
5619     }
5620     resId = std::stoul(resIdStr);
5621     return true;
5622 }
5623 
OnBundleUpdated(const std::string & bundleName,int userId)5624 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
5625 {
5626     taskScheduler_->PostAsyncTask([this, bundleName, where = __func__]() {
5627         if (startingWindowRdbMgr_ == nullptr || bundleMgr_ == nullptr) {
5628             TLOGNE(WmsLogTag::WMS_PATTERN, "%{public}s: rdb or bms is nullptr", where);
5629             return;
5630         }
5631         startingWindowRdbMgr_->DeleteDataByBundleName(bundleName);
5632         AppExecFwk::BundleInfo bundleInfo;
5633         bool ret = bundleMgr_->GetBundleInfoV9(bundleName,
5634             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_DISABLE) |
5635             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) |
5636             static_cast<uint32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY),
5637             bundleInfo, currentUserId_);
5638         if (ret == 0) {
5639             std::vector<std::pair<StartingWindowRdbItemKey, StartingWindowInfo>> inputValues;
5640             GetBundleStartingWindowInfos(GetIsDarkFromConfiguration() ,bundleInfo, inputValues);
5641             int64_t outInsertNum = -1;
5642             auto batchInsertRes = startingWindowRdbMgr_->BatchInsert(outInsertNum, inputValues);
5643             TLOGNI(WmsLogTag::WMS_PATTERN, "res:%{public}d, insert num:%{public}" PRId64, batchInsertRes, outInsertNum);
5644         }
5645     }, __func__);
5646     taskScheduler_->PostAsyncTask([this, bundleName]() {
5647         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5648         if (auto iter = startingWindowMap_.find(bundleName); iter != startingWindowMap_.end()) {
5649             startingWindowMap_.erase(iter);
5650         }
5651     }, __func__);
5652 }
5653 
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)5654 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
5655 {
5656     taskScheduler_->PostAsyncTask([this]() {
5657         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
5658         startingWindowMap_.clear();
5659     }, __func__);
5660 }
5661 
ExtractSupportWindowModeFromMetaData(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)5662 std::vector<AppExecFwk::SupportWindowMode> SceneSessionManager::ExtractSupportWindowModeFromMetaData(
5663     const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
5664 {
5665     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
5666     if (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode()) {
5667         auto metadata = abilityInfo->metadata;
5668         for (auto item : metadata) {
5669             if (item.name == "ohos.ability.window.supportWindowModeInFreeMultiWindow") {
5670                 updateWindowModes = ParseWindowModeFromMetaData(item.value);
5671             }
5672         }
5673     }
5674     if (updateWindowModes.empty()) {
5675         updateWindowModes = abilityInfo->windowModes;
5676     }
5677     return updateWindowModes;
5678 }
5679 
ParseWindowModeFromMetaData(const std::string & supportModesInFreeMultiWindow)5680 std::vector<AppExecFwk::SupportWindowMode> SceneSessionManager::ParseWindowModeFromMetaData(
5681     const std::string& supportModesInFreeMultiWindow)
5682 {
5683     std::vector<AppExecFwk::SupportWindowMode> updateWindowModes = {};
5684     std::stringstream supportModes(supportModesInFreeMultiWindow);
5685     std::string supportWindowMode;
5686     while (getline(supportModes, supportWindowMode, ',')) {
5687         if (supportWindowMode == "fullscreen") {
5688             updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FULLSCREEN);
5689         } else if (supportWindowMode == "split") {
5690             updateWindowModes.push_back(AppExecFwk::SupportWindowMode::SPLIT);
5691         } else if (supportWindowMode == "floating") {
5692             updateWindowModes.push_back(AppExecFwk::SupportWindowMode::FLOATING);
5693         }
5694     }
5695     return updateWindowModes;
5696 }
5697 
5698 
FillSessionInfo(sptr<SceneSession> & sceneSession)5699 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
5700 {
5701     const auto& sessionInfo = sceneSession->GetSessionInfo();
5702     if (sessionInfo.bundleName_.empty()) {
5703         TLOGE(WmsLogTag::DEFAULT, "bundleName_ is empty");
5704         return;
5705     }
5706     if (sessionInfo.isSystem_) {
5707         TLOGD(WmsLogTag::DEFAULT, "is system scene!");
5708         return;
5709     }
5710     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
5711         sessionInfo.moduleName_, IsAtomicServiceFreeInstall(sessionInfo));
5712     if (abilityInfo == nullptr) {
5713         TLOGE(WmsLogTag::DEFAULT, "Null");
5714         return;
5715     }
5716     if (sessionInfo.supportedWindowModes.empty()) {
5717         sceneSession->SetSessionInfoSupportedWindowModes(ExtractSupportWindowModeFromMetaData(abilityInfo));
5718     }
5719     sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
5720     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
5721     sceneSession->SetSessionInfoTime(GetCurrentTime());
5722     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
5723         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
5724     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
5725         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
5726     }
5727     SetSessionInfoStartWindowType(sceneSession);
5728     TLOGI(WmsLogTag::WMS_MAIN, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
5729         "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
5730         abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
5731         abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
5732 }
5733 
SetSessionInfoStartWindowType(const sptr<SceneSession> & sceneSession)5734 void SceneSessionManager::SetSessionInfoStartWindowType(const sptr<SceneSession>& sceneSession)
5735 {
5736     if (systemConfig_.IsPcOrPcMode() && !sceneSession->GetSessionInfo().isSetStartWindowType_) {
5737         StartingWindowInfo startingWindowInfo;
5738         GetStartupPage(sceneSession->GetSessionInfo(), startingWindowInfo);
5739         TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, startWindowType from rdb:%{public}s",
5740             sceneSession->GetPersistentId(), startingWindowInfo.startWindowType_.c_str());
5741         if (CONVERT_STRING_TO_START_WINDOW_TYPE_MAP.count(startingWindowInfo.startWindowType_) > 0) {
5742             sceneSession->EditSessionInfo().startWindowType_ =
5743                 CONVERT_STRING_TO_START_WINDOW_TYPE_MAP.at(startingWindowInfo.startWindowType_);
5744         }
5745         if (sceneSession->GetSessionInfo().startWindowType_ == StartWindowType::RETAIN_AND_INVISIBLE) {
5746             sceneSession->SetHidingStartingWindow(true);
5747         }
5748         TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, startWindowType:%{public}d",
5749             sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().startWindowType_);
5750     }
5751 }
5752 
RegisterGetStartWindowConfigCallback(const sptr<SceneSession> & sceneSession)5753 void SceneSessionManager::RegisterGetStartWindowConfigCallback(const sptr<SceneSession>& sceneSession)
5754 {
5755     if (sceneSession == nullptr) {
5756         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
5757         return;
5758     }
5759     sceneSession->RegisterGetStartWindowConfigFunc([this](const SessionInfo& sessionInfo, std::string& startWindowType) {
5760         StartingWindowInfo startingWindowInfo;
5761         GetStartupPage(sessionInfo, startingWindowInfo);
5762         startWindowType = startingWindowInfo.startWindowType_;
5763         TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d, startWindowType:%{public}s",
5764             sessionInfo.persistentId_, startWindowType.c_str());
5765     });
5766 }
5767 
5768 
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName,bool isAtomicServiceFreeInstall)5769 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
5770     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName,
5771     bool isAtomicServiceFreeInstall)
5772 {
5773     if (!bundleMgr_) {
5774         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
5775         return nullptr;
5776     }
5777     SessionInfoList list = {
5778         .uid_ = uId, .bundleName_ = bundleName, .abilityName_ = abilityName, .moduleName_ = moduleName
5779     };
5780     if (abilityInfoMap_.count(list)) {
5781         return abilityInfoMap_[list];
5782     }
5783     if (isAtomicServiceFreeInstall) {
5784         AppExecFwk::BundleInfo bundleInfo;
5785         auto flag = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
5786             static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
5787         bool ret = bundleMgr_->GetBundleInfoV9(bundleName, flag, bundleInfo, currentUserId_);
5788         if (ret) {
5789             TLOGE(WmsLogTag::WMS_LIFE, "Get bundle:%{public}s info from BMS failed!", bundleName.c_str());
5790             return nullptr;
5791         }
5792         for (const auto& hapModuleInfo : bundleInfo.hapModuleInfos) {
5793             if (!hapModuleInfo.abilityInfos.empty()) {
5794                 TLOGI(WmsLogTag::WMS_LIFE, "Get abilityInfo success in AtomicFreeInstall, bundle:%{public}s.",
5795                     bundleName.c_str());
5796 
5797                 // Atomic services only have one ability.
5798                 return std::make_shared<AppExecFwk::AbilityInfo>(hapModuleInfo.abilityInfos[0]);
5799             }
5800         }
5801         TLOGE(WmsLogTag::WMS_LIFE, "Get abilityInfo failed, bundleName:%{public}s.", bundleName.c_str());
5802         return nullptr;
5803     }
5804 
5805     AAFwk::Want want;
5806     want.SetElementName("", bundleName, abilityName, moduleName);
5807     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
5808     if (abilityInfo == nullptr) {
5809         TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
5810         return nullptr;
5811     }
5812     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
5813         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
5814         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
5815     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
5816     if (!ret) {
5817         TLOGE(WmsLogTag::DEFAULT, "Failed");
5818         return nullptr;
5819     }
5820     abilityInfoMap_[list] = abilityInfo;
5821     return abilityInfo;
5822 }
5823 
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)5824 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
5825     uint32_t& topWinId, uint32_t& zOrder)
5826 {
5827     const auto& subVec = session->GetSubSession();
5828     for (const auto& subSession : subVec) {
5829         if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
5830             TLOGW(WmsLogTag::WMS_SUB,
5831                 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
5832             continue;
5833         }
5834         if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5835              subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
5836             subSession->GetZOrder() > zOrder) {
5837             topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
5838             zOrder = subSession->GetZOrder();
5839             TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
5840                 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
5841         }
5842         if (subSession->GetSubSession().size() > 0) {
5843             GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
5844         }
5845     }
5846 }
5847 
5848 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)5849 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
5850 {
5851     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
5852     auto task = [this, mainWinId, &topWinId, callingPid]() {
5853         const auto& mainSession = GetSceneSession(mainWinId);
5854         if (mainSession == nullptr) {
5855             return WMError::WM_ERROR_INVALID_WINDOW;
5856         }
5857 
5858         if (callingPid != mainSession->GetCallingPid()) {
5859             TLOGNE(WmsLogTag::WMS_HIERARCHY, "Permission denied, not destroy by the same process");
5860             return WMError::WM_ERROR_INVALID_PERMISSION;
5861         }
5862         uint32_t zOrder = mainSession->GetZOrder();
5863         topWinId = mainWinId;
5864         GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
5865         TLOGNI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
5866             "zOrder: %{public}d", mainWinId, topWinId, zOrder);
5867         return WMError::WM_OK;
5868     };
5869 
5870     if (!Session::IsScbCoreEnabled()) {
5871         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
5872     }
5873     bool postNow = false;
5874     auto mainSession = GetSceneSession(mainWinId);
5875     if (mainSession != nullptr) {
5876         postNow = !(mainSession->GetUIStateDirty());
5877     }
5878     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
5879     if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
5880         taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
5881         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
5882     }
5883     TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
5884     {
5885         std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
5886         if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
5887             std::cv_status::timeout) {
5888             TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
5889         }
5890     }
5891     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
5892 }
5893 
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)5894 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
5895     int32_t windowId, int32_t& mainWindowId)
5896 {
5897     auto iter = sceneSessionMap.find(windowId);
5898     if (iter == sceneSessionMap.end()) {
5899         TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
5900         return WMError::WM_ERROR_NULLPTR;
5901     }
5902     sptr<SceneSession> sceneSession = iter->second;
5903     if (sceneSession == nullptr) {
5904         TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
5905         return WMError::WM_ERROR_NULLPTR;
5906     }
5907     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
5908         mainWindowId = sceneSession->GetPersistentId();
5909         return WMError::WM_OK;
5910     }
5911     if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
5912         WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
5913         return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
5914     }
5915     // not sub window, dialog, return invalid id
5916     mainWindowId = INVALID_SESSION_ID;
5917     return WMError::WM_OK;
5918 }
5919 
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)5920 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
5921 {
5922     if (windowId == INVALID_SESSION_ID) {
5923         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
5924         return WMError::WM_ERROR_INVALID_PARAM;
5925     }
5926     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5927     return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
5928 }
5929 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)5930 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
5931     const sptr<SceneSession>& sceneSession)
5932 {
5933     auto systemBarProperties = property->GetSystemBarProperty();
5934     for (auto iter : systemBarProperties) {
5935         if (iter.first == type) {
5936             sceneSession->SetSystemBarProperty(iter.first, iter.second);
5937             TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d enable %{public}d",
5938                 static_cast<int32_t>(iter.first), iter.second.enable_);
5939         }
5940     }
5941     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5942 }
5943 
5944 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)5945 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
5946     const sptr<SceneSession>& sceneSession)
5947 {
5948     if (!SessionPermission::IsSystemCalling()) {
5949         TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
5950         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5951     }
5952 
5953     sceneSession->SetTopmost(property->IsTopmost());
5954     return WMError::WM_OK;
5955 }
5956 
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)5957 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
5958     const sptr<SceneSession>& sceneSession)
5959 {
5960     auto propertyOld = sceneSession->GetSessionProperty();
5961     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
5962     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
5963     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
5964         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "property hideNonSystemFloatingWindows not change");
5965         return;
5966     }
5967 
5968     if (IsSessionVisibleForeground(sceneSession)) {
5969         if (hideNonSystemFloatingWindowsOld) {
5970             UpdateForceHideState(sceneSession, propertyOld, false);
5971         } else {
5972             UpdateForceHideState(sceneSession, property, true);
5973         }
5974     }
5975 }
5976 
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)5977 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
5978     const sptr<WindowSessionProperty>& property, bool add)
5979 {
5980     if (systemConfig_.IsPcWindow()) {
5981         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "IsPcWindow, ineffective");
5982         return;
5983     }
5984     if (property == nullptr) {
5985         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "property is null");
5986         return;
5987     }
5988     auto persistentId = sceneSession->GetPersistentId();
5989     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
5990     bool notifyAll = false;
5991     if (add) {
5992         if (property->GetHideNonSystemFloatingWindows()) {
5993             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
5994             notifyAll = !forceHideFloatOld;
5995         } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
5996             sceneSession->GetIsAncoForFloatingWindow()) {
5997             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
5998             if (forceHideFloatOld) {
5999                 sceneSession->NotifyForceHideChange(true);
6000             }
6001         }
6002     } else {
6003         if (property->GetHideNonSystemFloatingWindows()) {
6004             systemTopSceneSessionMap_.erase(persistentId);
6005             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
6006         } else if ((property->IsFloatingWindowAppType() && !property->GetSystemCalling()) ||
6007             sceneSession->GetIsAncoForFloatingWindow()) {
6008             nonSystemFloatSceneSessionMap_.erase(persistentId);
6009             if (property->GetForceHide()) {
6010                 sceneSession->NotifyForceHideChange(false);
6011             }
6012         }
6013     }
6014     if (notifyAll) {
6015         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
6016         for (const auto& item : nonSystemFloatSceneSessionMap_) {
6017             auto forceHideSceneSession = item.second;
6018             if (forceHideFloatNew != forceHideSceneSession->GetSessionProperty()->GetForceHide()) {
6019                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
6020             }
6021         }
6022     }
6023 }
6024 
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)6025 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
6026 {
6027 #ifdef POWER_MANAGER_ENABLE
6028     auto task = [this, sceneSession]() {
6029         if (sceneSession == nullptr) {
6030             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
6031             return;
6032         }
6033         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Win: %{public}s, is turn on%{public}d",
6034             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
6035         std::string identity = IPCSkeleton::ResetCallingIdentity();
6036         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
6037             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "turn screen on");
6038             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
6039         }
6040         // set ipc identity to raw
6041         IPCSkeleton::SetCallingIdentity(identity);
6042     };
6043     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
6044 
6045 #else
6046     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
6047 #endif
6048 }
6049 
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock,const std::string & screenLockPrefix,std::shared_ptr<PowerMgr::RunningLock> & screenLock)6050 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock,
6051     const std::string& screenLockPrefix, std::shared_ptr<PowerMgr::RunningLock>& screenLock)
6052 {
6053 #ifdef POWER_MANAGER_ENABLE
6054     wptr<SceneSession> weakSceneSession(sceneSession);
6055     auto task = [this, weakSceneSession, requireLock, &screenLockPrefix, &screenLock]() {
6056         auto sceneSession = weakSceneSession.promote();
6057         if (sceneSession == nullptr) {
6058             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
6059             return;
6060         }
6061         if (requireLock && screenLock == nullptr) {
6062             // reset ipc identity
6063             std::string identity = IPCSkeleton::ResetCallingIdentity();
6064             screenLock = PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(
6065                 screenLockPrefix + std::to_string(sceneSession->GetPersistentId()),
6066                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
6067             // set ipc identity to raw
6068             IPCSkeleton::SetCallingIdentity(identity);
6069         }
6070         if (screenLock == nullptr) {
6071             return;
6072         }
6073         auto currScreenId = sceneSession->GetSessionInfo().screenId_;
6074         auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
6075         if (auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currScreenId)) {
6076             sourceMode = screenSession->GetSourceMode();
6077         }
6078         bool shouldLock = requireLock && IsSessionVisibleForeground(sceneSession) && sourceMode != ScreenSourceMode::SCREEN_UNIQUE;
6079         TLOGNI(WmsLogTag::WMS_ATTRIBUTE,
6080             "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d]",
6081             sceneSession->GetWindowName().c_str(), sceneSession->GetSessionState(),
6082             sceneSession->IsVisible(), requireLock, shouldLock, currScreenId, sourceMode);
6083         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
6084         ErrCode res;
6085         std::string identity = IPCSkeleton::ResetCallingIdentity();
6086         if (shouldLock) {
6087             res = screenLock->Lock();
6088         } else {
6089             res = screenLock->UnLock();
6090         }
6091         // set ipc identity to raw
6092         IPCSkeleton::SetCallingIdentity(identity);
6093         if (res != ERR_OK) {
6094             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "handle keep screen running lock failed: [operation: %{public}d, "
6095                 "err: %{public}d]", requireLock, res);
6096         }
6097     };
6098     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
6099 #else
6100     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of PowerMgr");
6101 #endif
6102 }
6103 
NotifyVisibleChange(int32_t persistentId)6104 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
6105 {
6106     auto sceneSession = GetSceneSession(persistentId);
6107     if (sceneSession == nullptr) {
6108         return false;
6109     }
6110     HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
6111                        sceneSession->keepScreenLock_);
6112     HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
6113                        sceneSession->viewKeepScreenLock_);
6114     return true;
6115 }
6116 
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)6117 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
6118 {
6119 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
6120     if (GetDisplayBrightness() != brightness &&
6121         GetFocusedSessionId() == sceneSession->GetPersistentId()) {
6122         PostBrightnessTask(brightness);
6123     }
6124 #else
6125     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of DisplayPowerMgr");
6126 #endif
6127     brightnessSessionId_ = sceneSession->GetPersistentId();
6128     return WSError::WS_OK;
6129 }
6130 
PostBrightnessTask(float brightness)6131 void SceneSessionManager::PostBrightnessTask(float brightness)
6132 {
6133 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
6134     bool postTaskRet = true;
6135     bool isPC = systemConfig_.IsPcWindow();
6136     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
6137         if (!isPC) {
6138             auto task = [] {
6139                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
6140             };
6141             postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
6142         }
6143         SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
6144     } else {
6145         auto task = [brightness, isPC] {
6146             if (isPC) {
6147                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
6148                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
6149             } else {
6150                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
6151                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
6152             }
6153         };
6154         postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
6155         SetDisplayBrightness(brightness);
6156     }
6157     if (!postTaskRet) {
6158         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
6159     }
6160 #endif
6161 }
6162 
UpdateBrightness(int32_t persistentId)6163 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
6164 {
6165 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
6166     if (systemConfig_.IsPcWindow()) {
6167         return WSError::WS_OK;
6168     }
6169     auto sceneSession = GetSceneSession(persistentId);
6170     if (sceneSession == nullptr) {
6171         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
6172         return WSError::WS_ERROR_NULLPTR;
6173     }
6174     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
6175           sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLET_SWIPE_CARD ||
6176           sceneSession->GetSessionInfo().isSystem_)) {
6177         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window or wallet swipe card can set brightness");
6178         return WSError::WS_DO_NOTHING;
6179     }
6180     auto brightness = sceneSession->GetBrightness();
6181     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
6182     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
6183         if (IsNeedUpdateBrightness(persistentId, brightness)) {
6184             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
6185             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
6186             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
6187             brightnessSessionId_ = INVALID_WINDOW_ID;
6188         }
6189     } else {
6190         if (std::fabs(brightness - GetDisplayBrightness()) > std::numeric_limits<float>::min()) {
6191             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
6192             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
6193                 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
6194             SetDisplayBrightness(brightness);
6195         }
6196         brightnessSessionId_ = sceneSession->GetPersistentId();
6197     }
6198 #else
6199     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Can not found the sub system of DisplayPowerMgr");
6200 #endif
6201     return WSError::WS_OK;
6202 }
6203 
IsNeedUpdateBrightness(int32_t persistentId,float brightness)6204 bool SceneSessionManager::IsNeedUpdateBrightness(int32_t persistentId, float brightness)
6205 {
6206     if (std::fabs(brightness - GetDisplayBrightness()) < std::numeric_limits<float>::min()) {
6207         return false;
6208     }
6209     if (brightnessSessionId_ == persistentId) {
6210         return true;
6211     }
6212     auto brightnessSession = GetSceneSession(brightnessSessionId_);
6213     if (brightnessSession != nullptr && brightnessSession->IsSessionForeground()) {
6214         return false;
6215     }
6216     return true;
6217 }
6218 
GetCurrentUserId() const6219 int32_t SceneSessionManager::GetCurrentUserId() const
6220 {
6221     return currentUserId_;
6222 }
6223 
SetDisplayBrightness(float brightness)6224 void SceneSessionManager::SetDisplayBrightness(float brightness)
6225 {
6226     displayBrightness_ = brightness;
6227 }
6228 
GetDisplayBrightness() const6229 float SceneSessionManager::GetDisplayBrightness() const
6230 {
6231     return displayBrightness_;
6232 }
6233 
SetGestureNavigationEnabled(bool enable)6234 WMError SceneSessionManager::SetGestureNavigationEnabled(bool enable)
6235 {
6236     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
6237         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
6238         return WMError::WM_ERROR_NOT_SYSTEM_APP;
6239     }
6240     std::string callerBundleName = SessionPermission::GetCallingBundleName();
6241     TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
6242     auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
6243         SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
6244         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
6245             TLOGNE(WmsLogTag::WMS_EVENT, "callback func is null");
6246             return WMError::WM_OK;
6247         }
6248         if (gestureNavigationEnabledChangeFunc_) {
6249             gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
6250         }
6251         if (statusBarEnabledChangeFunc_) {
6252             statusBarEnabledChangeFunc_(enable, bundleName);
6253         }
6254         return WMError::WM_OK;
6255     };
6256     return taskScheduler_->PostSyncTask(task, "SetGestureNavigationEnabled");
6257 }
6258 
SetFocusedSessionId(const int32_t persistentId,const DisplayId displayId)6259 WSError SceneSessionManager::SetFocusedSessionId(const int32_t persistentId, const DisplayId displayId)
6260 {
6261     return windowFocusController_->UpdateFocusedSessionId(displayId, persistentId);
6262 }
6263 
GetFocusedSessionId(DisplayId displayId) const6264 int32_t SceneSessionManager::GetFocusedSessionId(DisplayId displayId) const
6265 {
6266     return windowFocusController_->GetFocusedSessionId(displayId);
6267 }
6268 
GetDisplayGroupId(DisplayId displayId) const6269 DisplayId SceneSessionManager::GetDisplayGroupId(DisplayId displayId) const
6270 {
6271     return windowFocusController_->GetDisplayGroupId(displayId);
6272 }
6273 
GetAllFocusedSessionList() const6274 std::vector<std::pair<DisplayId, int32_t>> SceneSessionManager::GetAllFocusedSessionList() const
6275 {
6276     return windowFocusController_->GetAllFocusedSessionList();
6277 }
6278 
GetFocusWindowInfo(FocusChangeInfo & focusInfo,DisplayId displayId)6279 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo, DisplayId displayId)
6280 {
6281     if (!SessionPermission::IsSACalling()) {
6282         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
6283         return;
6284     }
6285     taskScheduler_->PostSyncTask([this, &focusInfo, displayId] {
6286         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
6287         if (focusGroup == nullptr) {
6288             TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
6289             return WSError::WS_ERROR_DESTROYED_OBJECT;
6290         }
6291         if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
6292             focusInfo.windowId_ = sceneSession->GetWindowId();
6293             focusInfo.displayId_ = focusGroup->GetDisplayGroupId() == DEFAULT_DISPLAY_ID
6294                                         ? DEFAULT_DISPLAY_ID
6295                                         : sceneSession->GetDisplayId();
6296             focusInfo.pid_ = sceneSession->GetCallingPid();
6297             focusInfo.uid_ = sceneSession->GetCallingUid();
6298             focusInfo.windowType_ = sceneSession->GetWindowType();
6299             focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
6300             TLOGND(WmsLogTag::WMS_FOCUS, "Get focus session info success");
6301             return WSError::WS_OK;
6302         }
6303         return WSError::WS_ERROR_DESTROYED_OBJECT;
6304     }, __func__);
6305 }
6306 
AddFocusGroup(DisplayGroupId displayGroupId,DisplayId displayId)6307 WSError SceneSessionManager::AddFocusGroup(DisplayGroupId displayGroupId, DisplayId displayId)
6308 {
6309     return windowFocusController_->AddFocusGroup(displayGroupId, displayId);
6310 }
6311 
RemoveFocusGroup(DisplayGroupId displayGroupId,DisplayId displayId)6312 WSError SceneSessionManager::RemoveFocusGroup(DisplayGroupId displayGroupId, DisplayId displayId)
6313 {
6314     return windowFocusController_->RemoveFocusGroup(displayGroupId, displayId);
6315 }
6316 
SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)6317 WSError SceneSessionManager::SendPointerEventForHover(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
6318 {
6319     if (!SessionPermission::IsSACalling()) {
6320         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
6321         return WSError::WS_ERROR_INVALID_PERMISSION;
6322     }
6323     if (pointerEvent == nullptr) {
6324         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is nullptr");
6325         return WSError::WS_ERROR_NULLPTR;
6326     }
6327     bool isHoverDown = pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_HOVER_ENTER &&
6328         pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
6329     if (!isHoverDown) {
6330         TLOGE(WmsLogTag::WMS_EVENT, "pointer event is not hover down");
6331         return WSError::WS_ERROR_INVALID_PARAM;
6332     }
6333     return taskScheduler_->PostSyncTask([this, &pointerEvent]() {
6334         int32_t windowId = pointerEvent->GetAgentWindowId();
6335         TLOGNI(WmsLogTag::WMS_EVENT, "windowId: %{public}d", windowId);
6336         auto sceneSession = GetSceneSession(windowId);
6337         if (sceneSession == nullptr) {
6338             TLOGNE(WmsLogTag::WMS_EVENT, "session is nullptr");
6339             return WSError::WS_ERROR_INVALID_SESSION;
6340         }
6341         return sceneSession->SendPointerEventForHover(pointerEvent);
6342     }, __func__);
6343 }
6344 
IsValidDigitString(const std::string & windowIdStr)6345 static bool IsValidDigitString(const std::string& windowIdStr)
6346 {
6347     if (windowIdStr.empty()) {
6348         return false;
6349     }
6350     for (char ch : windowIdStr) {
6351         if (ch >= '0' && ch <= '9') {
6352             continue;
6353         }
6354         TLOGE(WmsLogTag::DEFAULT, "invalid window id");
6355         return false;
6356     }
6357     return true;
6358 }
6359 
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)6360 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
6361 {
6362     if (sceneSession == nullptr) {
6363         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
6364         return;
6365     }
6366     sceneSession->SetSessionExceptionListener([this, where = __func__](
6367         const SessionInfo& info, const ExceptionInfo& exceptionInfo , bool startFail = false) {
6368         auto task = [this, info, where] {
6369             auto session = GetSceneSession(info.persistentId_);
6370             if (session == nullptr) {
6371                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
6372                 return;
6373             }
6374             if (session->GetSessionInfo().isSystem_) {
6375                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where, session->GetPersistentId());
6376                 return;
6377             }
6378             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
6379                 where, info.errorCode, info.persistentId_);
6380             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
6381                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
6382                 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
6383                     "or foreground timeout, id: %{public}d", info.persistentId_);
6384                 listenerController_->NotifySessionClosed(session->GetSessionInfo());
6385             }
6386         };
6387         taskScheduler_->PostVoidSyncTask(task, "sessionException");
6388     }, false);
6389     TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
6390 }
6391 
RegisterVisibilityChangedDetectFunc(const sptr<SceneSession> & sceneSession)6392 void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)
6393 {
6394     if (sceneSession == nullptr) {
6395         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
6396         return;
6397     }
6398     sceneSession->SetVisibilityChangedDetectFunc(
6399         [this](int32_t pid, bool isVisible, bool newIsVisible) THREAD_SAFETY_GUARD(SCENE_GUARD) {
6400         if (isVisible == newIsVisible || pid == -1) {
6401             return;
6402         }
6403         auto windowPidVisibilityInfo = sptr<WindowPidVisibilityInfo>::MakeSptr();
6404         windowPidVisibilityInfo->pid_ = pid;
6405         int32_t currentCount = 0;
6406         int32_t beforeCount = 0;
6407         if (visibleWindowCountMap_.find(pid) != visibleWindowCountMap_.end()) {
6408             beforeCount = visibleWindowCountMap_[pid];
6409         }
6410         currentCount = newIsVisible ? beforeCount + 1 : beforeCount - 1;
6411         visibleWindowCountMap_[pid] = currentCount;
6412         if (visibleWindowCountMap_[pid] == 0) {
6413             visibleWindowCountMap_.erase(pid);
6414         }
6415         if (beforeCount == 0 && currentCount == 1) {
6416             TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid);
6417             windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE;
6418             SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
6419         } else if (beforeCount == 1 && currentCount == 0) {
6420             TLOGNI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid);
6421             windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE;
6422             SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
6423         } else if (beforeCount < 0 || currentCount < 0) {
6424             TLOGNE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid);
6425             RecoveryVisibilityPidCount(pid);
6426         }
6427     });
6428 }
6429 
RecoveryVisibilityPidCount(int32_t pid)6430 void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid)
6431 {
6432     int32_t count = 0;
6433     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6434     for (const auto& [_, session] : sceneSessionMap_) {
6435         if (session && session->GetCallingPid() == pid && session->IsVisible()) {
6436             count++;
6437         }
6438     }
6439     if (count > 0) {
6440         visibleWindowCountMap_[pid] = count;
6441     }
6442 }
6443 
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)6444 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
6445 {
6446     if (sceneSession == nullptr) {
6447         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
6448         return;
6449     }
6450     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
6451         auto sceneSession = GetSceneSession(persistentId);
6452         if (sceneSession == nullptr) {
6453             TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
6454             return;
6455         }
6456         if (sceneSession->GetSessionInfo().isSystem_) {
6457             TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, id: %{public}d is system",
6458                 sceneSession->GetPersistentId());
6459             return;
6460         }
6461         auto abilityInfo = sceneSession->GetSessionInfo().abilityInfo;
6462         if (abilityInfo == nullptr) {
6463             TLOGNW(WmsLogTag::WMS_SYSTEM, "NotifySessionSnapshotFunc, abilityInfo is nullptr");
6464             return;
6465         }
6466         if (!abilityInfo->excludeFromMissions) {
6467             listenerController_->NotifySessionSnapshotChanged(persistentId);
6468         }
6469     };
6470     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
6471     TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d", sceneSession->GetPersistentId());
6472 }
6473 
RegisterRequestVsyncFunc(const sptr<SceneSession> & sceneSession)6474 void SceneSessionManager::RegisterRequestVsyncFunc(const sptr<SceneSession>& sceneSession)
6475 {
6476     if (sceneSession == nullptr) {
6477         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
6478         return;
6479     }
6480     sceneSession->SetRequestNextVsyncFunc([this](const std::shared_ptr<VsyncCallback>& callback) {
6481         vsyncStation_->RequestVsync(callback);
6482     });
6483 }
6484 
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)6485 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
6486 {
6487     if (sceneSession == nullptr) {
6488         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
6489         return;
6490     }
6491     AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
6492         config.duration_ = rotateAnimationConfig_.duration_;
6493     };
6494     sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
6495     TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d",
6496         sceneSession->GetPersistentId());
6497 }
6498 
CloseSyncTransaction(std::function<void ()> func)6499 void SceneSessionManager::CloseSyncTransaction(std::function<void()> func)
6500 {
6501     auto task = [this, param = std::move(func), where = __func__] () {
6502         if (!closeSyncFunc_) {
6503             closeSyncFunc_ = std::move(param);
6504         }
6505         bool isLastFrameLayoutFinished = true;
6506         IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
6507         if (isLastFrameLayoutFinished) {
6508             closeSyncFunc_();
6509         } else {
6510             needCloseSync_ = true;
6511         }
6512     };
6513     taskScheduler_->PostAsyncTask(task, __func__);
6514 }
6515 
NotifySessionForCallback(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)6516 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
6517 {
6518     if (sceneSession == nullptr) {
6519         TLOGW(WmsLogTag::DEFAULT, "session is null");
6520         return;
6521     }
6522     if (sceneSession->GetSessionInfo().isSystem_) {
6523         TLOGW(WmsLogTag::DEFAULT, "id: %{public}d is system", sceneSession->GetPersistentId());
6524         return;
6525     }
6526     if (sceneSession->GetSessionInfo().appIndex_ != 0) {
6527         TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, appIndex: %{public}d, id: %{public}d",
6528                sceneSession->GetSessionInfo().appIndex_, sceneSession->GetPersistentId());
6529         listenerController_->NotifySessionLifecycleEvent(
6530             ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
6531         return;
6532     }
6533     if (needRemoveSession) {
6534         TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, needRemoveSession, id: %{public}d", sceneSession->GetPersistentId());
6535         listenerController_->NotifySessionLifecycleEvent(
6536             ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
6537         return;
6538     }
6539     if (sceneSession->GetSessionInfo().abilityInfo == nullptr) {
6540         TLOGW(WmsLogTag::DEFAULT, "abilityInfo is null, id: %{public}d", sceneSession->GetPersistentId());
6541     } else if ((sceneSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
6542                (sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6543         TLOGI(WmsLogTag::DEFAULT, "NotifyDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
6544             sceneSession->GetPersistentId());
6545         listenerController_->NotifySessionLifecycleEvent(
6546             ISessionLifecycleListener::SessionLifecycleEvent::DESTROYED, sceneSession->GetSessionInfo());
6547         return;
6548     }
6549     TLOGI(WmsLogTag::DEFAULT, "NotifyClosed, id: %{public}d", sceneSession->GetPersistentId());
6550     listenerController_->NotifySessionClosed(sceneSession->GetSessionInfo());
6551 }
6552 
NotifyWindowInfoChangeFromSession(int32_t persistentId)6553 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
6554 {
6555     TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d", persistentId);
6556     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6557     if (sceneSession == nullptr) {
6558         TLOGE(WmsLogTag::DEFAULT, "sceneSession nullptr");
6559         return;
6560     }
6561 
6562     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
6563 }
6564 
IsSessionVisible(const sptr<SceneSession> & session) const6565 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session) const
6566 {
6567     if (session == nullptr) {
6568         return false;
6569     }
6570     if (Session::IsScbCoreEnabled()) {
6571         return session->IsVisible();
6572     }
6573     const auto& state = session->GetSessionState();
6574     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
6575         const auto& mainOrFloatSession = session->GetMainOrFloatSession();
6576         if (mainOrFloatSession == nullptr) {
6577             TLOGE(WmsLogTag::WMS_SUB, "Can not find parent for this sub window, id: %{public}d",
6578                 session->GetPersistentId());
6579             return false;
6580         }
6581         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
6582             const auto mainOrFloatSessionState = mainOrFloatSession->GetSessionState();
6583             if (mainOrFloatSessionState == SessionState::STATE_INACTIVE ||
6584                 mainOrFloatSessionState == SessionState::STATE_BACKGROUND) {
6585                 TLOGD(WmsLogTag::WMS_SUB, "Parent of this sub window is at background, id: %{public}d",
6586                     session->GetPersistentId());
6587                 return false;
6588             }
6589             TLOGD(WmsLogTag::WMS_SUB, "Sub window is at foreground, id: %{public}d", session->GetPersistentId());
6590             return true;
6591         }
6592         TLOGD(WmsLogTag::WMS_SUB, "Sub window is at background, id: %{public}d", session->GetPersistentId());
6593         return false;
6594     }
6595 
6596     if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
6597         TLOGD(WmsLogTag::WMS_LIFE, "Window is at foreground, id: %{public}d", session->GetPersistentId());
6598         return true;
6599     }
6600     TLOGD(WmsLogTag::WMS_LIFE, "Window is at background, id: %{public}d", session->GetPersistentId());
6601     return false;
6602 }
6603 
IsSessionVisibleForeground(const sptr<SceneSession> & session) const6604 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session) const
6605 {
6606     if (session == nullptr) {
6607         return false;
6608     }
6609     if (Session::IsScbCoreEnabled()) {
6610         return session->IsVisibleForeground();
6611     }
6612     return IsSessionVisible(session);
6613 }
6614 
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)6615 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
6616 {
6617     if (session == nullptr) {
6618         return;
6619     }
6620     int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
6621     WSRect rect = session->GetSessionRect();
6622     std::string sName;
6623     if (session->GetSessionInfo().isSystem_) {
6624         sName = session->GetSessionInfo().abilityName_;
6625     } else {
6626         sName = session->GetWindowName();
6627     }
6628     uint32_t flag = session->GetSessionProperty()->GetWindowFlags();
6629     uint64_t displayId = session->GetSessionProperty()->GetDisplayId();
6630     uint32_t orientation = 0;
6631     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
6632         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
6633     // std::setw is used to set the output width and different width values are set to keep the format aligned.
6634     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
6635         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
6636         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
6637         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
6638         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
6639         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
6640         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
6641         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
6642         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
6643         << "[ "
6644         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
6645         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
6646         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
6647         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
6648         << "]"
6649         << " [ "
6650         << std::left << std::setw(OFFSET_MAX_WIDTH) << GetFloatWidth(OFFSET_MAX_WIDTH, session->GetOffsetX())
6651         << std::left << std::setw(OFFSET_MAX_WIDTH) << GetFloatWidth(OFFSET_MAX_WIDTH, session->GetOffsetY())
6652         << "]"
6653         << " [ "
6654         << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetScaleX())
6655         << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetScaleY())
6656         << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetPivotX())
6657         << std::left << std::setw(SCALE_MAX_WIDTH) << GetFloatWidth(SCALE_MAX_WIDTH, session->GetPivotY())
6658         << "]"
6659         << std::endl;
6660 }
6661 
GetFloatWidth(const int width,float value)6662 std::string SceneSessionManager::GetFloatWidth(const int width, float value)
6663 {
6664     std::ostringstream oss;
6665     oss << value;
6666     std::string strValue = oss.str();
6667     return (strValue.size() > static_cast<size_t>(width)) ? strValue.substr(0, width) : strValue;
6668 }
6669 
DumpFocusInfo(std::ostringstream & oss)6670 void SceneSessionManager::DumpFocusInfo(std::ostringstream& oss)
6671 {
6672     auto defaultFocusedSessionId = windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID);
6673     oss << "Focus window: " << defaultFocusedSessionId << std::endl;
6674     std::vector<std::pair<DisplayId, int32_t>> allFocusedSessionList =
6675         windowFocusController_->GetAllFocusedSessionList();
6676     oss << "All Focus window: " << std::endl;
6677     if (allFocusedSessionList.size() > 0) {
6678         for (const auto& focusState : allFocusedSessionList) {
6679             oss << "DisplayId: " << focusState.first << " WindowId: " << focusState.second << std::endl;
6680         }
6681     }
6682 }
6683 
GetAllSessionDumpInfo(std::string & dumpInfo)6684 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
6685 {
6686     std::ostringstream oss;
6687     oss << "-------------------------------------ScreenGroup 0"
6688         << "-------------------------------------" << std::endl;
6689     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
6690         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]" << std::endl;
6691     std::vector<sptr<SceneSession>> allSession;
6692     std::vector<sptr<SceneSession>> backgroundSession;
6693     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
6694     {
6695         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6696         sceneSessionMapCopy = sceneSessionMap_;
6697     }
6698     for (const auto& elem : sceneSessionMapCopy) {
6699         auto curSession = elem.second;
6700         if (curSession == nullptr) {
6701             TLOGD(WmsLogTag::DEFAULT, "nullptr");
6702             continue;
6703         }
6704         if (!curSession->GetSessionInfo().isSystem_ &&
6705             (curSession->GetSessionState() < SessionState::STATE_FOREGROUND ||
6706             curSession->GetSessionState() > SessionState::STATE_BACKGROUND)) {
6707             TLOGW(WmsLogTag::DEFAULT, "id:%{public}d,invalid state:%{public}u",
6708                  curSession->GetPersistentId(), curSession->GetSessionState());
6709              continue;
6710          }
6711         if (IsSessionVisibleForeground(curSession)) {
6712             allSession.push_back(curSession);
6713         } else {
6714             backgroundSession.push_back(curSession);
6715         }
6716     }
6717     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
6718     uint32_t count = 0;
6719     for (const auto& session : allSession) {
6720         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
6721             oss << "---------------------------------------------------------------------------------------"
6722                 << std::endl;
6723         }
6724         DumpSessionInfo(session, oss);
6725         count++;
6726     }
6727     DumpFocusInfo(oss);
6728     oss << "SingleHand: X[" << singleHandTransform_.posX << "] Y[" << singleHandTransform_.posY << "] scale["
6729         << singleHandTransform_.scaleX << "]" << std::endl;
6730     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
6731     oss << "Highlighted windows: " << GetHighlightIdsStr() << std::endl;
6732     dumpInfo.append(oss.str());
6733     return WSError::WS_OK;
6734 }
6735 
GetAllSessionDumpDetailInfo(std::string & dumpInfo)6736 WSError SceneSessionManager::GetAllSessionDumpDetailInfo(std::string& dumpInfo)
6737 {
6738     std::ostringstream oss;
6739     std::vector<sptr<SceneSession>> allSession;
6740     std::vector<sptr<SceneSession>> backgroundSession;
6741 
6742     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
6743     {
6744         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6745         sceneSessionMapCopy = sceneSessionMap_;
6746     }
6747     for (const auto& elem : sceneSessionMapCopy) {
6748         auto curSession = elem.second;
6749         if (curSession == nullptr) {
6750             continue;
6751         }
6752         if (IsSessionVisibleForeground(curSession)) {
6753             allSession.push_back(curSession);
6754         } else {
6755             backgroundSession.push_back(curSession);
6756         }
6757     }
6758     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
6759     HidumpController::GetInstance().GetAllSessionDumpDetailedInfo(oss, allSession, backgroundSession);
6760     dumpInfo.append(oss.str());
6761     return WSError::WS_OK;
6762 }
6763 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)6764 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
6765 {
6766     dumpRootSceneFunc_ = func;
6767 }
6768 
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)6769 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
6770     const std::vector<std::string>& params, std::string& dumpInfo)
6771 {
6772     std::vector<std::string> resetParams;
6773     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
6774     if (resetParams.empty()) {
6775         TLOGND(WmsLogTag::DEFAULT, "do not dump ui info");
6776         return;
6777     }
6778 
6779     if (!session->GetSessionInfo().isSystem_) {
6780         TLOGD(WmsLogTag::DEFAULT, "Dump normal session, not system");
6781         dumpInfoFuture_.ResetLock({});
6782         session->DumpSessionElementInfo(resetParams);
6783         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
6784         for (auto& info: infos) {
6785             dumpInfo.append(info).append("\n");
6786         }
6787     } else {
6788         TLOGD(WmsLogTag::DEFAULT, "Dump system session");
6789         std::vector<std::string> infos;
6790         dumpRootSceneFunc_(session, resetParams, infos);
6791         for (auto& info: infos) {
6792             dumpInfo.append(info).append("\n");
6793         }
6794     }
6795 }
6796 
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)6797 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
6798     const std::string& strId)
6799 {
6800     uint64_t persistentId = std::stoull(strId);
6801     auto session = GetSceneSession(persistentId);
6802     if (session == nullptr) {
6803         return WSError::WS_ERROR_INVALID_PARAM;
6804     }
6805     auto sessionProperty = session->GetSessionProperty();
6806     WSRect rect = session->GetSessionRect();
6807     std::string isVisible = session->IsVisible() ? "true" : "false";
6808     std::string focusable = session->GetFocusable() ? "true" : "false";
6809     std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
6810     bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
6811     std::string isPrivacyMode = privacyMode ? "true" : "false";
6812     bool isFirstFrameAvailable = true;
6813     std::ostringstream oss;
6814     oss << "WindowName: " << session->GetWindowName()  << std::endl;
6815     oss << "DisplayId: " << session->GetSessionProperty()->GetDisplayId() << std::endl;
6816     oss << "WinId: " << session->GetPersistentId() << std::endl;
6817     oss << "Pid: " << session->GetCallingPid() << std::endl;
6818     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
6819     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
6820     oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
6821     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
6822     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
6823     oss << "IsVisible: " << isVisible << std::endl;
6824     oss << "isRSVisible: " << (session->GetRSVisible() ? "true" : "false") << std::endl;
6825     oss << "Focusable: "  << focusable << std::endl;
6826     oss << "DecoStatus: "  << decoStatus << std::endl;
6827     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
6828     oss << "WindowRect: " << "[ "
6829         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
6830         << " ]" << std::endl;
6831     oss << "scaleX: " << session->GetScaleX() << std::endl;
6832     oss << "scaleY: " << session->GetScaleY() << std::endl;
6833     oss << "Offset: " << "[ "
6834         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
6835     oss << "Scale: " << "[ "
6836         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
6837         << session->GetPivotX() << ", " << session->GetPivotY()
6838         << " ]" << std::endl;
6839     oss << "ParentWindowId: " << session->GetParentPersistentId() << std::endl;
6840     dumpInfo.append(oss.str());
6841 
6842     DumpSessionElementInfo(session, params, dumpInfo);
6843     return WSError::WS_OK;
6844 }
6845 
GetSCBDebugDumpInfo(std::string && cmd,std::string & dumpInfo)6846 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)
6847 {
6848     std::string filePath;
6849     {
6850         auto rootContext = rootSceneContextWeak_.lock();
6851         filePath = rootContext != nullptr ? rootContext->GetFilesDir() + "/wms.dump" : "";
6852     }
6853     // publish data
6854     bool ret = eventHandler_->PostSyncTask(
6855         [this, filePath = std::move(filePath), cmd = std::move(cmd)] {
6856             return scbDumpSubscriber_->Publish(cmd, filePath);
6857         }, "PublishSCBDumper");
6858     if (!ret) {
6859         return WSError::WS_ERROR_INVALID_OPERATION;
6860     }
6861     // get response event
6862     auto task = [this, &dumpInfo] {
6863         dumpInfo.append(scbDumpSubscriber_->GetDebugDumpInfo(WAIT_TIME));
6864         return WSError::WS_OK;
6865     };
6866     eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
6867     return WSError::WS_OK;
6868 }
6869 
NotifyDumpInfoResult(const std::vector<std::string> & info)6870 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
6871 {
6872     dumpInfoFuture_.SetValue(info);
6873     TLOGD(WmsLogTag::DEFAULT, "NotifyDumpInfoResult");
6874 }
6875 
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)6876 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
6877 {
6878     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
6879         TLOGE(WmsLogTag::DEFAULT, "GetSessionDumpInfo permission denied!");
6880         return WSError::WS_ERROR_INVALID_PERMISSION;
6881     }
6882 
6883     if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
6884         return GetAllSessionDumpInfo(dumpInfo);
6885     }
6886     if (params.size() == 1 && params[0] == ARG_DUMP_DETAIL) { // 1: params num
6887         return GetAllSessionDumpDetailInfo(dumpInfo);
6888     }
6889     if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
6890         return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
6891     }
6892     if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2: params num
6893         std::string cmd;
6894         std::for_each(params.begin() + 1, params.end(),
6895                         [&cmd](const std::string& value) {
6896                             cmd += value;
6897                             cmd += ' ';
6898                         });
6899         return GetSCBDebugDumpInfo(std::move(cmd), dumpInfo);
6900     }
6901     if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
6902         return GetTotalUITreeInfo(dumpInfo);
6903     }
6904     if (params.size() >= 2 && params[0] == ARG_DUMP_RECORD) { // 2: params num
6905         std::vector<std::string> resetParams;
6906         resetParams.assign(params.begin() + 1, params.end());
6907         SessionChangeRecorder::GetInstance().GetSceneSessionNeedDumpInfo(resetParams, dumpInfo);
6908         return WSError::WS_OK;
6909     }
6910     return WSError::WS_ERROR_INVALID_OPERATION;
6911 }
6912 
GetTotalUITreeInfo(std::string & dumpInfo)6913 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
6914 {
6915     TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
6916     if (dumpUITreeFunc_) {
6917         dumpUITreeFunc_(dumpInfo);
6918     } else {
6919         TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
6920     }
6921     return WSError::WS_OK;
6922 }
6923 
SetDumpUITreeFunc(const DumpUITreeFunc & func)6924 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
6925 {
6926     dumpUITreeFunc_ = func;
6927 }
6928 
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)6929 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
6930 {
6931     onFlushUIParamsFunc_ = std::move(func);
6932 }
6933 
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)6934 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
6935 {
6936     isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
6937 }
6938 
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)6939 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
6940 {
6941     taskScheduler_->PostAsyncTask([this, displayId, visible] {
6942         statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
6943         TLOGNI(WmsLogTag::WMS_IMMS, "set default visibility, "
6944             "display id %{public}" PRIu64 " visible %{public}d", displayId, visible);
6945     }, __func__);
6946 }
6947 
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)6948 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
6949 {
6950     return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
6951            statusBarDefaultVisibilityPerDisplay_[displayId] : true;
6952 }
6953 
FocusIDChange(int32_t persistentId,const sptr<SceneSession> & sceneSession)6954 void FocusIDChange(int32_t persistentId, const sptr<SceneSession>& sceneSession)
6955 {
6956     // notify RS
6957     TLOGD(WmsLogTag::WMS_FOCUS, "current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s, "
6958         "abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
6959         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
6960         sceneSession->GetSessionInfo().bundleName_.c_str(),
6961         sceneSession->GetSessionInfo().abilityName_.c_str(),
6962         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
6963     uint64_t focusNodeId = 0; // 0 means invalid
6964     if (sceneSession->GetSurfaceNode() == nullptr) {
6965         TLOGW(WmsLogTag::WMS_FOCUS, "focused window surfaceNode is null");
6966     } else {
6967         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
6968     }
6969     FocusAppInfo appInfo = {
6970         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
6971         sceneSession->GetSessionInfo().bundleName_,
6972         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
6973     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
6974 }
6975 
6976 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)6977 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
6978 {
6979     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
6980     {
6981         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6982         for (auto& iter : sceneSessionMap_) {
6983             ret.push_back(iter);
6984         }
6985     }
6986     std::sort(ret.begin(), ret.end(), cmp);
6987     return ret;
6988 }
6989 
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)6990 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
6991 {
6992     if (isFromTopToBottom) {
6993         TraverseSessionTreeFromTopToBottom(func);
6994     } else {
6995         TraverseSessionTreeFromBottomToTop(func);
6996     }
6997     return;
6998 }
6999 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)7000 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
7001 {
7002     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
7003         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
7004         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
7005         return lhsZOrder < rhsZOrder;
7006     };
7007     auto sceneSessionVector = GetSceneSessionVector(cmp);
7008 
7009     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
7010         auto session = iter->second;
7011         if (session == nullptr) {
7012             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7013             continue;
7014         }
7015         if (func(session)) {
7016             return;
7017         }
7018     }
7019     return;
7020 }
7021 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)7022 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
7023 {
7024     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7025     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
7026         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
7027         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
7028         return lhsZOrder < rhsZOrder;
7029     };
7030     auto sceneSessionVector = GetSceneSessionVector(cmp);
7031     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
7032     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
7033         auto session = iter->second;
7034         if (session == nullptr) {
7035             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
7036             continue;
7037         }
7038         if (func(session)) {
7039             return;
7040         }
7041     }
7042     return;
7043 }
7044 
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)7045 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
7046     FocusChangeReason reason)
7047 {
7048     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
7049     auto sceneSession = GetSceneSession(persistentId);
7050     if (sceneSession == nullptr) {
7051         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7052         return WMError::WM_ERROR_NULLPTR;
7053     }
7054     int32_t callingPid = IPCSkeleton::GetCallingPid();
7055     if (callingPid != sceneSession->GetCallingPid() &&
7056         !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
7057         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
7058         return WMError::WM_ERROR_INVALID_CALLING;
7059     }
7060     auto task = [this, persistentId, isFocused, byForeground, reason]() {
7061         if (isFocused) {
7062             RequestSessionFocus(persistentId, byForeground, reason);
7063         } else {
7064             RequestSessionUnfocus(persistentId, reason);
7065         }
7066     };
7067     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
7068     focusChangeReason_ = reason;
7069     return WMError::WM_OK;
7070 }
7071 
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)7072 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
7073     FocusChangeReason reason)
7074 {
7075     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
7076     auto task = [this, persistentId, isFocused, byForeground, reason]() {
7077         if (isFocused) {
7078             if (reason == FocusChangeReason::FOREGROUND) {
7079                 RequestSessionFocusImmediately(persistentId);
7080                 return;
7081             }
7082             if (reason == FocusChangeReason::MOVE_UP) {
7083                 auto session = GetSceneSession(persistentId);
7084                 if (session && !session->IsFocused()) {
7085                     PostProcessFocusState state = { true, true, byForeground, reason };
7086                     session->SetPostProcessFocusState(state);
7087                 }
7088                 return;
7089             }
7090             // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
7091             if (reason == FocusChangeReason::CLICK) {
7092                 return;
7093             }
7094             if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
7095                 auto session = GetSceneSession(persistentId);
7096                 if (session && !session->IsFocused()) {
7097                     PostProcessFocusState state = { true, true, byForeground, reason };
7098                     session->SetPostProcessFocusState(state);
7099                 }
7100             }
7101         } else {
7102             RequestSessionUnfocus(persistentId, reason);
7103         }
7104     };
7105     taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
7106     return WMError::WM_OK;
7107 }
7108 
RequestFocusStatusBySA(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)7109 WMError SceneSessionManager::RequestFocusStatusBySA(int32_t persistentId, bool isFocused,
7110     bool byForeground, FocusChangeReason reason)
7111 {
7112     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
7113     if (!SessionPermission::IsSACalling()) {
7114         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, only support SA calling.");
7115         return WMError::WM_ERROR_INVALID_PERMISSION;
7116     }
7117     auto sceneSession = GetSceneSession(persistentId);
7118     if (sceneSession == nullptr) {
7119         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7120         return WMError::WM_ERROR_NULLPTR;
7121     }
7122     auto task = [this, persistentId, isFocused, byForeground, reason]() {
7123         if (isFocused) {
7124             RequestSessionFocus(persistentId, byForeground, reason);
7125         } else {
7126             RequestSessionUnfocus(persistentId, reason);
7127         }
7128     };
7129     taskScheduler_->PostAsyncTask(task, "RequestFocusOnPreviousWindow" + std::to_string(persistentId));
7130     return WMError::WM_OK;
7131 }
7132 
RequestAllAppSessionUnfocus()7133 void SceneSessionManager::RequestAllAppSessionUnfocus()
7134 {
7135     auto task = [this]() {
7136         RequestAllAppSessionUnfocusInner();
7137     };
7138     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
7139     return;
7140 }
7141 
7142 /**
7143  * request focus and ignore its state
7144  * only used when app main window start before foreground
7145  */
RequestSessionFocusImmediately(int32_t persistentId,bool blockNotifyUntilVisible)7146 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId, bool blockNotifyUntilVisible)
7147 {
7148     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, blockNotify: %{public}d", persistentId, blockNotifyUntilVisible);
7149     auto sceneSession = GetSceneSession(persistentId);
7150     if (sceneSession == nullptr) {
7151         TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
7152         return WSError::WS_ERROR_INVALID_SESSION;
7153     }
7154     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7155     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7156     if (focusGroup == nullptr) {
7157         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7158         return WSError::WS_ERROR_NULLPTR;
7159     }
7160     // base block
7161     WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
7162     if (basicCheckRet != WSError::WS_OK) {
7163         return basicCheckRet;
7164     }
7165     if (!sceneSession->CheckFocusable()) {
7166         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
7167         return WSError::WS_DO_NOTHING;
7168     }
7169     if (!sceneSession->IsFocusedOnShow()) {
7170         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
7171         return WSError::WS_DO_NOTHING;
7172     }
7173 
7174     // specific block
7175     FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
7176     WSError specificCheckRet = RequestFocusSpecificCheck(displayId, sceneSession, true, reason);
7177     if (specificCheckRet != WSError::WS_OK) {
7178         return specificCheckRet;
7179     }
7180     auto needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7181     focusGroup->SetNeedBlockNotifyUnfocusStatus(needBlockNotifyFocusStatusUntilForeground);
7182     if (!sceneSession->GetSessionInfo().isSystem_ && !blockNotifyUntilVisible && systemConfig_.IsPcWindow()) {
7183         if (!sceneSession->IsSessionForeground()) {
7184             focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
7185         }
7186     } else if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
7187         focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
7188     }
7189     ShiftFocus(displayId, sceneSession, false, reason);
7190     return WSError::WS_OK;
7191 }
7192 
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)7193 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
7194 {
7195     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
7196         persistentId, byForeground, reason);
7197     auto sceneSession = GetSceneSession(persistentId);
7198     if (sceneSession == nullptr) {
7199         TLOGE(WmsLogTag::WMS_FOCUS, "[WMSComm]session is nullptr");
7200         return WSError::WS_ERROR_INVALID_SESSION;
7201     }
7202     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7203     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7204     if (focusGroup == nullptr) {
7205         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7206         return WSError::WS_ERROR_NULLPTR;
7207     }
7208     WSError checkRet = RequestSessionFocusCheck(sceneSession, focusGroup, persistentId, byForeground, reason);
7209     if (checkRet != WSError::WS_OK) {
7210         return checkRet;
7211     }
7212     focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
7213     focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7214     ShiftFocus(displayId, sceneSession, false, reason);
7215     return WSError::WS_OK;
7216 }
7217 
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)7218 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
7219 {
7220     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
7221     if (persistentId == INVALID_SESSION_ID) {
7222         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid: %{public}d", persistentId);
7223         return WSError::WS_ERROR_INVALID_SESSION;
7224     }
7225     auto sceneSession = GetSceneSession(persistentId);
7226     if (sceneSession == nullptr) {
7227         TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr: %{public}d", persistentId);
7228         return WSError::WS_ERROR_INVALID_SESSION;
7229     }
7230     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
7231     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7232     if (focusGroup == nullptr) {
7233         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7234         return WSError::WS_ERROR_NULLPTR;
7235     }
7236     auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
7237     if (persistentId != focusGroup->GetFocusedSessionId() &&
7238         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
7239         TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
7240         return WSError::WS_DO_NOTHING;
7241     }
7242     // if pop menu created by desktop request unfocus, back to desktop
7243     auto lastSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
7244     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
7245         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
7246         RequestSessionFocus(focusGroup->GetLastFocusedSessionId(), false) == WSError::WS_OK) {
7247             TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
7248             return WSError::WS_OK;
7249     }
7250     auto nextSession = GetNextFocusableSession(displayId, persistentId);
7251     if (nextSession == nullptr) {
7252         DumpAllSessionFocusableInfo(persistentId);
7253     }
7254     focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
7255     focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7256 
7257     if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
7258         return WSError::WS_OK;
7259     }
7260     if (nextSession && !nextSession->IsSessionForeground() && !nextSession->GetSessionInfo().isSystem_) {
7261         focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(true);
7262     }
7263     return ShiftFocus(displayId, nextSession, true, reason);
7264 }
7265 
RequestAllAppSessionUnfocusInner()7266 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
7267 {
7268     TLOGI(WmsLogTag::WMS_FOCUS, "in");
7269     auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
7270     if (focusGroup == nullptr) {
7271         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
7272         return WSError::WS_ERROR_NULLPTR;
7273     }
7274     auto focusedSession = GetSceneSession(focusGroup->GetFocusedSessionId());
7275     if (!focusedSession) {
7276         TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
7277         return WSError::WS_DO_NOTHING;
7278     }
7279     if (!focusedSession->IsAppSession()) {
7280         TLOGW(WmsLogTag::WMS_FOCUS, "Focused session is non app: %{public}d", focusGroup->GetFocusedSessionId());
7281         return WSError::WS_DO_NOTHING;
7282     }
7283     auto nextSession = GetTopFocusableNonAppSession();
7284 
7285     focusGroup->SetNeedBlockNotifyUnfocusStatus(focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground());
7286     focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
7287     return ShiftFocus(DEFAULT_DISPLAY_ID, nextSession, true, FocusChangeReason::WIND);
7288 }
7289 
RequestSessionFocusCheck(const sptr<SceneSession> & sceneSession,const sptr<FocusGroup> & focusGroup,int32_t persistentId,bool byForeground,FocusChangeReason reason)7290 WSError SceneSessionManager::RequestSessionFocusCheck(const sptr<SceneSession>& sceneSession,
7291     const sptr<FocusGroup>& focusGroup, int32_t persistentId, bool byForeground, FocusChangeReason reason)
7292 {
7293     if (reason == FocusChangeReason::REQUEST_WITH_CHECK_SUB_WINDOW &&
7294         CheckRequestFocusSubWindowImmediately(sceneSession)) {
7295         TLOGD(WmsLogTag::WMS_FOCUS, "sub window focused");
7296         return WSError::WS_DO_NOTHING;
7297     }
7298     WSError basicCheckRet = RequestFocusBasicCheck(persistentId, focusGroup);
7299     if (basicCheckRet != WSError::WS_OK) {
7300         return basicCheckRet;
7301     }
7302     if (!sceneSession->CheckFocusable() || !IsSessionVisibleForeground(sceneSession)) {
7303         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
7304         return WSError::WS_DO_NOTHING;
7305     }
7306     if (!sceneSession->IsFocusedOnShow()) {
7307         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
7308         return WSError::WS_DO_NOTHING;
7309     }
7310     if (!sceneSession->IsFocusableOnShow() &&
7311         (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
7312         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
7313         return WSError::WS_DO_NOTHING;
7314     }
7315     // subwindow/dialog state block
7316     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
7317         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
7318         GetSceneSession(sceneSession->GetParentPersistentId()) &&
7319         !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
7320             TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
7321                 sceneSession->GetParentPersistentId());
7322             return WSError::WS_DO_NOTHING;
7323     }
7324     // specific block
7325     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession->GetSessionProperty()->GetDisplayId(),
7326         sceneSession, byForeground, reason);
7327     if (specificCheckRet != WSError::WS_OK) {
7328         return specificCheckRet;
7329     }
7330     return WSError::WS_OK;
7331 }
7332 
RequestFocusBasicCheck(int32_t persistentId,const sptr<FocusGroup> & focusGroup)7333 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId, const sptr<FocusGroup>& focusGroup)
7334 {
7335     // basic focus rule
7336     if (persistentId == INVALID_SESSION_ID) {
7337         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
7338         return WSError::WS_ERROR_INVALID_SESSION;
7339     }
7340     if (focusGroup == nullptr) {
7341         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
7342         return WSError::WS_ERROR_NULLPTR;
7343     }
7344     if (persistentId == focusGroup->GetFocusedSessionId()) {
7345         TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
7346         return WSError::WS_DO_NOTHING;
7347     }
7348     return WSError::WS_OK;
7349 }
7350 
7351 /**
7352  * @note @window.focus
7353  * When high zOrder System Session unfocus, check if the last focused app window can focus.
7354  */
CheckLastFocusedAppSessionFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & nextSession)7355 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(const sptr<SceneSession>& focusedSession,
7356     const sptr<SceneSession>& nextSession)
7357 {
7358     if (focusedSession == nullptr || nextSession == nullptr) {
7359         return false;
7360     }
7361     auto displayId = focusedSession->GetSessionProperty()->GetDisplayId();
7362     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7363     if (focusGroup == nullptr) {
7364         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7365         return false;
7366     }
7367     auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
7368     TLOGI(WmsLogTag::WMS_FOCUS, "last=%{public}d, next=%{public}d",
7369         lastFocusedAppSessionId, nextSession->GetPersistentId());
7370 
7371     if (lastFocusedAppSessionId == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId) {
7372         return false;
7373     }
7374 
7375     if (!focusedSession->IsSystemSessionAboveApp()) {
7376         return false;
7377     }
7378 
7379     auto mode = nextSession->GetWindowMode();
7380     // only when next session is app, and in split or floation
7381     if (nextSession->IsAppSession() &&
7382         (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
7383          mode == WindowMode::WINDOW_MODE_FLOATING)) {
7384         if (RequestSessionFocus(lastFocusedAppSessionId, false, FocusChangeReason::LAST_FOCUSED_APP) ==
7385             WSError::WS_OK) {
7386             return true;
7387         }
7388         focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
7389     }
7390     return false;
7391 }
7392 
7393 /**
7394  * When switching focus, check if the blockingType window has been  traversed downwards.
7395  *
7396  * @return true: traversed downwards, false: not.
7397  */
CheckFocusIsDownThroughBlockingType(const sptr<SceneSession> & requestSceneSession,const sptr<SceneSession> & focusedSession,bool includingAppSession)7398 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(const sptr<SceneSession>& requestSceneSession,
7399     const sptr<SceneSession>& focusedSession, bool includingAppSession)
7400 {
7401     uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
7402     uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
7403     auto displayId = requestSceneSession->GetSessionProperty()->GetDisplayId();
7404     TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
7405         requestSessionZOrder, focusedSessionZOrder);
7406     if  (requestSessionZOrder < focusedSessionZOrder)  {
7407         auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(displayId, requestSessionZOrder,
7408             includingAppSession);
7409         uint32_t topNearestBlockingZOrder = 0;
7410         if  (topNearestBlockingFocusSession)  {
7411             topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
7412             TLOGI(WmsLogTag::WMS_FOCUS,
7413                   "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
7414                   topNearestBlockingZOrder:  %{public}d, topNearestBlockingId: %{public}d",
7415                   requestSessionZOrder, focusedSessionZOrder,
7416                   topNearestBlockingZOrder, topNearestBlockingFocusSession->GetPersistentId());
7417         }
7418         if  (focusedSessionZOrder >=  topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder)  {
7419             TLOGD(WmsLogTag::WMS_FOCUS,  "focus pass through, needs to be intercepted");
7420             return true;
7421         }
7422     }
7423     TLOGD(WmsLogTag::WMS_FOCUS, "not through");
7424     return false;
7425 }
7426 
CheckTopmostWindowFocus(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession)7427 bool SceneSessionManager::CheckTopmostWindowFocus(const sptr<SceneSession>& focusedSession,
7428     const sptr<SceneSession>& sceneSession)
7429 {
7430     bool isFocusedMainSessionTopmost =
7431         focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
7432     auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
7433     bool isFocusedSessionParentTopmost = parentSession &&
7434         parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
7435     if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
7436         (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
7437         return true;
7438     }
7439     return false;
7440 }
7441 
CheckRequestFocusImmediately(const sptr<SceneSession> & sceneSession)7442 bool SceneSessionManager::CheckRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
7443 {
7444     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
7445          (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
7446         (ProcessModalTopmostRequestFocusImmediately(sceneSession) == WSError::WS_OK ||
7447          ProcessDialogRequestFocusImmediately(sceneSession) == WSError::WS_OK)) {
7448         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
7449         return true;
7450     }
7451     return false;
7452 }
7453 
CheckRequestFocusSubWindowImmediately(const sptr<SceneSession> & sceneSession)7454 bool SceneSessionManager::CheckRequestFocusSubWindowImmediately(const sptr<SceneSession>& sceneSession)
7455 {
7456     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
7457          SessionHelper::IsSubWindow(sceneSession->GetWindowType())) &&
7458         (ProcessSubWindowRequestFocusImmediately(sceneSession) == WSError::WS_OK ||
7459          ProcessDialogRequestFocusImmediately(sceneSession) == WSError::WS_OK)) {
7460         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or sub window get focused");
7461         return true;
7462     }
7463     return false;
7464 }
7465 
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)7466 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
7467     const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
7468 {
7469     if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
7470         focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
7471         return false;
7472     }
7473     if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
7474         return false;
7475     }
7476     return sceneSession->GetZOrder() < focusedSession->GetZOrder();
7477 }
7478 
RequestFocusSpecificCheck(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)7479 WSError SceneSessionManager::RequestFocusSpecificCheck(DisplayId displayId, const sptr<SceneSession>& sceneSession,
7480     bool byForeground, FocusChangeReason reason)
7481 {
7482     TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
7483     int32_t persistentId = sceneSession->GetPersistentId();
7484     if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
7485         TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
7486         return WSError::WS_ERROR_INVALID_OPERATION;
7487     }
7488     // dialog get focus
7489     if (CheckRequestFocusImmediately(sceneSession)) {
7490         return WSError::WS_DO_NOTHING;
7491     }
7492     // blocking-type session will block lower zOrder request focus
7493     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7494     auto focusedSession = GetSceneSession(focusedSessionId);
7495     if (focusedSession) {
7496         TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d",  reason,
7497             byForeground);
7498         if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
7499             // return ok if focused session is topmost
7500             return WSError::WS_OK;
7501         }
7502         if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
7503             sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
7504             TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
7505             byForeground = false;
7506         }
7507         if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession,  focusedSession,  true))  {
7508             TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
7509             return WSError::WS_DO_NOTHING;
7510         }
7511         if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
7512             !byForeground)  {
7513             if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
7514                 && focusedSession->IsAppSession()) {
7515                 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
7516                 return WSError::WS_OK;
7517             }
7518         }
7519         bool isBlockingType = focusedSession->IsAppSession() ||
7520             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
7521         // temp check
7522         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
7523             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
7524                 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
7525                     persistentId);
7526                 return WSError::WS_DO_NOTHING;
7527         }
7528         // desktop click temp check
7529         if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
7530             TLOGD(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
7531             return WSError::WS_DO_NOTHING;
7532         }
7533     }
7534     return WSError::WS_OK;
7535 }
7536 
IsParentSessionVisible(const sptr<SceneSession> & session)7537 bool SceneSessionManager::IsParentSessionVisible(const sptr<SceneSession>& session)
7538 {
7539     if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
7540         session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
7541         auto parentSession = GetSceneSession(session->GetParentPersistentId());
7542         return parentSession == nullptr || IsSessionVisibleForeground(parentSession);
7543     }
7544     return true;
7545 }
7546 
DumpAllSessionFocusableInfo(int32_t persistentId)7547 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
7548 {
7549     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
7550     auto func = [this](const sptr<SceneSession>& session) {
7551         if (session == nullptr) {
7552             return false;
7553         }
7554         bool parentVisible = IsParentSessionVisible(session);
7555         bool sessionVisible = IsSessionVisible(session);
7556         TLOGNI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
7557             "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
7558             session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
7559             session->GetFocusable(), sessionVisible, parentVisible);
7560         return false;
7561     };
7562     TraverseSessionTree(func, true);
7563 }
7564 
GetNextFocusableSession(DisplayId displayId,int32_t persistentId)7565 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(DisplayId displayId, int32_t persistentId)
7566 {
7567     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
7568     bool previousFocusedSessionFound = false;
7569     DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
7570     sptr<SceneSession> nextFocusableSession = nullptr;
7571     auto func = [this, persistentId, &previousFocusedSessionFound, &nextFocusableSession, displayGroupId](sptr<SceneSession> session) {
7572         if (session == nullptr) {
7573             return false;
7574         }
7575         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7576             displayGroupId) {
7577             return false;
7578         }
7579         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
7580             TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
7581             return false;
7582         }
7583         if (previousFocusedSessionFound && session->CheckFocusable() &&
7584             session->IsVisibleNotBackground() && IsParentSessionVisible(session)) {
7585             nextFocusableSession = session;
7586             return true;
7587         }
7588         if (session->GetPersistentId() == persistentId) {
7589             previousFocusedSessionFound = true;
7590         }
7591         return false;
7592     };
7593     TraverseSessionTree(func, true);
7594     sptr<SceneSession> topFloatingSession = GetNextFocusableSessionWhenFloatWindowExist(displayGroupId, persistentId);
7595     if (topFloatingSession != nullptr && nextFocusableSession != nullptr && nextFocusableSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) {
7596         TLOGI(WmsLogTag::WMS_FOCUS, "topFloatingSessionId: %{public}d", topFloatingSession->GetPersistentId());
7597         return topFloatingSession;
7598     }
7599     return nextFocusableSession;
7600 }
7601 
GetNextFocusableSessionWhenFloatWindowExist(DisplayId displayGroupId,int32_t persistentId)7602 sptr<SceneSession> SceneSessionManager::GetNextFocusableSessionWhenFloatWindowExist(DisplayId displayGroupId,
7603                                                                                     int32_t persistentId)
7604 {
7605     bool isPhoneOrPadWithoutPcMode =
7606         (systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) && !systemConfig_.IsFreeMultiWindowMode();
7607     if (!isPhoneOrPadWithoutPcMode) {
7608         return nullptr;
7609     }
7610     auto topFloatingSession = GetTopFloatingSession(displayGroupId, persistentId);
7611     auto sceneSession = GetSceneSession(persistentId);
7612     if (topFloatingSession != nullptr && SessionHelper::IsMainWindow(sceneSession->GetWindowType()) &&
7613         sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
7614         return topFloatingSession;
7615     }
7616     return nullptr;
7617 }
7618 
GetTopFloatingSession(DisplayId displayGroupId,int32_t persistentId)7619 sptr<SceneSession> SceneSessionManager::GetTopFloatingSession(DisplayId displayGroupId, int32_t persistentId)
7620 {
7621     bool previousFocusedSessionFound = false;
7622     sptr<SceneSession> topFloatingSession = nullptr;
7623     auto func = [this, persistentId, &previousFocusedSessionFound, &topFloatingSession, displayGroupId](sptr<SceneSession> session) {
7624         if (session == nullptr || topFloatingSession != nullptr || previousFocusedSessionFound) {
7625             return false;
7626         }
7627         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7628             displayGroupId) {
7629             return false;
7630         }
7631         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
7632             TLOGND(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
7633             return false;
7634         }
7635         // need to be floating window
7636         if (session->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
7637             return false;
7638         }
7639         // need to be main window
7640         if (!SessionHelper::IsMainWindow(session->GetWindowType())) {
7641             return false;
7642         }
7643 
7644         if (session->CheckFocusable() && session->IsVisible()) {
7645             topFloatingSession = session;
7646             return true;
7647         }
7648         if (session->GetPersistentId() == persistentId) {
7649             previousFocusedSessionFound = true;
7650         }
7651         return false;
7652     };
7653     TraverseSessionTree(func, true);
7654     return topFloatingSession;
7655 }
7656 
7657 /**
7658  * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
7659  * and it is the closest;
7660  */
GetTopNearestBlockingFocusSession(DisplayId displayId,uint32_t zOrder,bool includingAppSession)7661 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(DisplayId displayId, uint32_t zOrder,
7662     bool includingAppSession)
7663 {
7664     sptr<SceneSession> ret = nullptr;
7665     DisplayId displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
7666     auto func = [this, &ret, zOrder, includingAppSession, displayGroupId](sptr<SceneSession> session) {
7667         if (session == nullptr) {
7668             return false;
7669         }
7670         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7671             displayGroupId) {
7672             return false;
7673         }
7674         uint32_t sessionZOrder = session->GetZOrder();
7675         if (sessionZOrder <= zOrder) { // must be above the target session
7676             return false;
7677         }
7678         if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7679             TLOGND(WmsLogTag::WMS_FOCUS, "topmost window do not block");
7680             return false;
7681         }
7682         auto parentSession = GetSceneSession(session->GetParentPersistentId());
7683         if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
7684             parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost()) {
7685             TLOGND(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
7686             return false;
7687         }
7688 
7689         if (IsSessionVisibleForeground(session) && CheckBlockingFocus(session, includingAppSession)) {
7690             ret = session;
7691             return true;
7692         }
7693         return false;
7694     };
7695     TraverseSessionTree(func, false);
7696     return ret;
7697 }
7698 
CheckBlockingFocus(const sptr<SceneSession> & session,bool includingAppSession)7699 bool SceneSessionManager::CheckBlockingFocus(const sptr<SceneSession>& session, bool includingAppSession)
7700 {
7701     if (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) {
7702         TLOGD(WmsLogTag::WMS_FOCUS, "system window blocked");
7703         return true;
7704     }
7705 
7706     bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
7707     if (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION) {
7708         return true;
7709     }
7710     if (includingAppSession && session->IsAppSession()) {
7711         TLOGD(WmsLogTag::WMS_FOCUS,
7712               "id: %{public}d, isFloatType: %{public}d, isFloatMode: %{public}d", session->GetPersistentId(),
7713               session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT,
7714               session->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING);
7715         bool isPcOrPcMode =
7716             systemConfig_.IsPcWindow() || (isPhoneOrPad && systemConfig_.IsFreeMultiWindowMode());
7717         if (isPcOrPcMode && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
7718             return false;
7719         }
7720         bool isPhoneOrPadWithoutPcMode = isPhoneOrPad && !systemConfig_.IsFreeMultiWindowMode();
7721         if (isPhoneOrPadWithoutPcMode && session->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
7722             SessionHelper::IsMainWindow(session->GetWindowType()) && !session->GetIsMidScene()) {
7723             return false;
7724         }
7725         return true;
7726     }
7727     return false;
7728 }
7729 
GetTopFocusableNonAppSession()7730 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
7731 {
7732     TLOGD(WmsLogTag::WMS_FOCUS, "in.");
7733     sptr<SceneSession> ret = nullptr;
7734     auto func = [this, &ret](sptr<SceneSession> session) {
7735         if (session == nullptr) {
7736             return false;
7737         }
7738         if (windowFocusController_->GetDisplayGroupId(session->GetSessionProperty()->GetDisplayId()) !=
7739             DEFAULT_DISPLAY_ID) {
7740             return false;
7741         }
7742         if (session->IsAppSession()) {
7743             return session->GetZOrder() == 0 ? false : true;
7744         }
7745         if (session->CheckFocusable() && IsSessionVisibleForeground(session)) {
7746             ret = session;
7747         }
7748         return false;
7749     };
7750     TraverseSessionTree(func, false);
7751     return ret;
7752 }
7753 
SetShiftFocusListener(const ProcessShiftFocusFunc & func)7754 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
7755 {
7756     TLOGD(WmsLogTag::WMS_FOCUS, "in");
7757     shiftFocusFunc_ = func;
7758 }
7759 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)7760 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
7761 {
7762     TLOGD(WmsLogTag::WMS_FOCUS, "in");
7763     notifySCBAfterFocusedFunc_ = func;
7764 }
7765 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)7766 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
7767 {
7768     TLOGD(WmsLogTag::WMS_FOCUS, "in");
7769     notifySCBAfterUnfocusedFunc_ = func;
7770 }
7771 
SetSCBFocusChangeListener(const NotifyDiffSCBAfterUpdateFocusFunc && func)7772 void SceneSessionManager::SetSCBFocusChangeListener(const NotifyDiffSCBAfterUpdateFocusFunc&& func)
7773 {
7774     TLOGD(WmsLogTag::WMS_FOCUS, "in");
7775     notifyDiffSCBAfterUnfocusedFunc_ = std::move(func);
7776 }
7777 
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)7778 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
7779 {
7780     TLOGD(WmsLogTag::DEFAULT, "in");
7781     callingSessionIdChangeFunc_ = func;
7782 }
7783 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)7784 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
7785 {
7786     TLOGD(WmsLogTag::DEFAULT, "in");
7787     startUIAbilityErrorFunc_ = func;
7788 }
7789 
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)7790 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
7791     const AbilityManagerCollaboratorRegisteredFunc& func)
7792 {
7793     auto task = [this, func] {
7794         abilityManagerCollaboratorRegisteredFunc_ = func;
7795     };
7796     taskScheduler_->PostAsyncTask(task, __func__);
7797 }
7798 
ShiftFocus(DisplayId displayId,const sptr<SceneSession> & nextSession,bool isProactiveUnfocus,FocusChangeReason reason)7799 WSError SceneSessionManager::ShiftFocus(DisplayId displayId, const sptr<SceneSession>& nextSession,
7800     bool isProactiveUnfocus, FocusChangeReason reason)
7801 {
7802     // unfocus
7803     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
7804     int32_t focusedId = focusedSessionId;
7805     auto focusedSession = GetSceneSession(focusedSessionId);
7806     UpdateFocusStatus(displayId, focusedSession, false);
7807     // focus
7808     int32_t nextId = INVALID_SESSION_ID;
7809     if (nextSession == nullptr) {
7810         std::string sessionLog(GetAllSessionFocusInfo());
7811         TLOGW(WmsLogTag::WMS_FOCUS, "next session nullptr! id: %{public}d, info: %{public}s",
7812             focusedSessionId, sessionLog.c_str());
7813     } else {
7814         nextId = nextSession->GetPersistentId();
7815     }
7816     UpdateFocusStatus(displayId, nextSession, true);
7817     UpdateHighlightStatus(displayId, focusedSession, nextSession, isProactiveUnfocus);
7818     if (shiftFocusFunc_ != nullptr) {
7819         auto displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
7820         shiftFocusFunc_(nextId, displayGroupId);
7821     }
7822     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
7823     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
7824     if (!scbPrevFocus && scbCurrFocus) {
7825         if (notifySCBAfterFocusedFunc_ != nullptr) {
7826             notifySCBAfterFocusedFunc_(nextSession->GetSessionProperty()->GetDisplayId());
7827         }
7828     } else if (scbPrevFocus && !scbCurrFocus) {
7829         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
7830             notifySCBAfterUnfocusedFunc_(focusedSession->GetSessionProperty()->GetDisplayId());
7831         }
7832     } else if (scbPrevFocus && scbCurrFocus) {
7833         DisplayId focusedSessionDisplayId = focusedSession->GetSessionProperty()->GetDisplayId();
7834         DisplayId nextSessionDisplayId = nextSession->GetSessionProperty()->GetDisplayId();
7835         if (notifyDiffSCBAfterUnfocusedFunc_ != nullptr && focusedSessionDisplayId != nextSessionDisplayId) {
7836             notifyDiffSCBAfterUnfocusedFunc_(focusedSessionDisplayId, nextSessionDisplayId);
7837         }
7838     }
7839     TLOGI(WmsLogTag::WMS_FOCUS, "[%{public}" PRIu64 ",%{public}d,%{public}d,%{public}d",
7840         displayId, focusedId, nextId, reason);
7841     return WSError::WS_OK;
7842 }
7843 
UpdateFocusStatus(DisplayId displayId,const sptr<SceneSession> & sceneSession,bool isFocused)7844 void SceneSessionManager::UpdateFocusStatus(DisplayId displayId, const sptr<SceneSession>& sceneSession,
7845     bool isFocused)
7846 {
7847     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7848     if (focusGroup == nullptr) {
7849         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7850         return;
7851     }
7852     bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7853     bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
7854     if (sceneSession == nullptr) {
7855         TLOGW(WmsLogTag::WMS_FOCUS, "session is nullptr");
7856         if (isFocused) {
7857             SetFocusedSessionId(INVALID_SESSION_ID, displayId);
7858             focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
7859             auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
7860             NotifyUnFocusedByMission(prevSession);
7861         }
7862         return;
7863     }
7864     TLOGD(WmsLogTag::WMS_FOCUS, "name: %{public}s, id: %{public}d, isFocused: %{public}d, displayId: %{public}" PRIu64,
7865           sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused, displayId);
7866     // set focused
7867     if (isFocused) {
7868         SetFocusedSessionId(sceneSession->GetPersistentId(), displayId);
7869         if (sceneSession->IsAppOrLowerSystemSession()) {
7870             focusGroup->SetLastFocusedAppSessionId(sceneSession->GetPersistentId());
7871         }
7872     }
7873     sceneSession->UpdateFocus(isFocused);
7874     // notify listenerController unfocused
7875     auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
7876     if (isFocused && MissionChanged(prevSession, sceneSession)) {
7877         NotifyUnFocusedByMission(prevSession);
7878     }
7879     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground) || (!isFocused && !needBlockNotifyUnfocusStatus)) {
7880         NotifyFocusStatus(sceneSession, isFocused, focusGroup);
7881     }
7882 }
7883 
7884 /** @note @window.focus */
UpdateHighlightStatus(DisplayId displayId,const sptr<SceneSession> & preSceneSession,const sptr<SceneSession> & currSceneSession,bool isProactiveUnfocus)7885 void SceneSessionManager::UpdateHighlightStatus(DisplayId displayId, const sptr<SceneSession>& preSceneSession,
7886     const sptr<SceneSession>& currSceneSession, bool isProactiveUnfocus)
7887 {
7888     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
7889     if (focusGroup == nullptr) {
7890         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
7891         return;
7892     }
7893     bool needBlockHighlightNotify = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
7894     if(isProactiveUnfocus){
7895         TLOGD(WmsLogTag::WMS_FOCUS, "proactiveUnfocus");
7896         RemoveHighlightSessionIds(preSceneSession);
7897     }
7898     if (currSceneSession == nullptr) {
7899         TLOGE(WmsLogTag::WMS_FOCUS, "currSceneSession is nullptr");
7900         return;
7901     }
7902     if(currSceneSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
7903         TLOGD(WmsLogTag::WMS_FOCUS, "exclusively highlighted");
7904         SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7905         return;
7906     }
7907     if(SessionHelper::IsSystemWindow(currSceneSession->GetWindowType())) {
7908         TLOGD(WmsLogTag::WMS_FOCUS, "system highlighted");
7909         AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7910         return;
7911     }
7912     if(currSceneSession->IsSameMainSession(preSceneSession)) {
7913         TLOGD(WmsLogTag::WMS_FOCUS, "related highlighted");
7914         AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7915         return;
7916     }
7917     TLOGD(WmsLogTag::WMS_FOCUS, "highlighted");
7918     SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
7919 }
7920 
7921 /** @note @window.focus */
SetHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)7922 void SceneSessionManager::SetHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
7923 {
7924     if (sceneSession == nullptr) {
7925         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7926         return;
7927     }
7928     {
7929         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7930         for (auto persistentId : highlightIds_) {
7931             auto session = GetSceneSession(persistentId);
7932             if (session == nullptr) {
7933                 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr");
7934                 continue;
7935             }
7936             if (sceneSession->GetPersistentId() != persistentId) {
7937                 session->UpdateHighlightStatus(false, false);
7938             }
7939         }
7940         sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
7941         highlightIds_.clear();
7942         highlightIds_.insert(sceneSession->GetPersistentId());
7943     }
7944     TLOGI(WmsLogTag::WMS_FOCUS, "%{public}s", GetHighlightIdsStr().c_str());
7945 }
7946 
7947 /** @note @window.focus */
AddHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)7948 void SceneSessionManager::AddHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
7949 {
7950     if (sceneSession == nullptr) {
7951         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7952         return;
7953     }
7954     sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
7955     {
7956         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7957         highlightIds_.insert(sceneSession->GetPersistentId());
7958     }
7959     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
7960 }
7961 
7962 /** @note @window.focus */
RemoveHighlightSessionIds(const sptr<SceneSession> & sceneSession)7963 void SceneSessionManager::RemoveHighlightSessionIds(const sptr<SceneSession>& sceneSession)
7964 {
7965     if (sceneSession == nullptr) {
7966         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
7967         return;
7968     }
7969     {
7970         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7971         if (highlightIds_.find(sceneSession->GetPersistentId()) != highlightIds_.end()) {
7972             sceneSession->UpdateHighlightStatus(false, false);
7973             highlightIds_.erase(sceneSession->GetPersistentId());
7974         } else {
7975             TLOGE(WmsLogTag::WMS_FOCUS, "not found scene session with id: %{public}d", sceneSession->GetPersistentId());
7976         }
7977 
7978     }
7979     TLOGI(WmsLogTag::WMS_FOCUS, "%{public}s", GetHighlightIdsStr().c_str());
7980 }
7981 
7982 /** @note @window.focus */
GetHighlightIdsStr()7983 std::string SceneSessionManager::GetHighlightIdsStr()
7984 {
7985     std::ostringstream oss;
7986     {
7987         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
7988         for (auto it = highlightIds_.begin(); it != highlightIds_.end(); it++) {
7989             oss << *it;
7990             if(std::next(it) != highlightIds_.end()) {
7991                 oss << ", ";
7992             }
7993         }
7994 
7995     }
7996     return oss.str();
7997 }
7998 
NotifyFocusStatus(const sptr<SceneSession> & sceneSession,bool isFocused,const sptr<FocusGroup> & focusGroup)7999 void SceneSessionManager::NotifyFocusStatus(const sptr<SceneSession>& sceneSession, bool isFocused,
8000     const sptr<FocusGroup>& focusGroup)
8001 {
8002     if (focusGroup == nullptr) {
8003         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr");
8004         return;
8005     }
8006     int32_t persistentId = sceneSession->GetPersistentId();
8007 
8008     TLOGI(WmsLogTag::WMS_FOCUS,
8009         "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
8010         sceneSession->GetSessionInfo().bundleName_.c_str(),
8011         sceneSession->GetSessionInfo().abilityName_.c_str(),
8012         sceneSession->GetWindowNameAllType().c_str(),
8013         persistentId, isFocused);
8014     if (isFocused) {
8015         if (IsSessionVisibleForeground(sceneSession)) {
8016             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
8017         }
8018         UpdateBrightness(focusGroup->GetFocusedSessionId());
8019         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
8020     }
8021     DisplayId focusGroupId = focusGroup->GetDisplayGroupId() == DEFAULT_DISPLAY_ID ? DEFAULT_DISPLAY_ID : sceneSession->GetDisplayId();
8022     // notify window manager
8023     sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
8024         sceneSession->GetWindowId(),
8025         focusGroupId,
8026         sceneSession->GetCallingPid(),
8027         sceneSession->GetCallingUid(),
8028         sceneSession->GetWindowType(),
8029         sceneSession->GetAbilityToken()
8030     );
8031     SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
8032     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
8033     sceneSession->NotifyFocusStatus(isFocused);
8034     // notify listenerController focused
8035     auto prevSession = GetSceneSession(focusGroup->GetLastFocusedSessionId());
8036     if (isFocused && MissionChanged(prevSession, sceneSession)) {
8037         NotifyFocusedByMission(sceneSession);
8038     }
8039 }
8040 
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)8041 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
8042     const std::string& reason)
8043 {
8044     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
8045     nlohmann::json payload;
8046     payload.emplace("uid", uid);
8047     payload.emplace("bundleName", bundleName);
8048     payload.emplace("reason", reason);
8049     nlohmann::json reply;
8050     return ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
8051 }
8052 
NotifyFocusStatusByMission(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)8053 void SceneSessionManager::NotifyFocusStatusByMission(const sptr<SceneSession>& prevSession,
8054     const sptr<SceneSession>& currSession)
8055 {
8056     if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
8057         TLOGD(WmsLogTag::WMS_FOCUS, "Unfocused, id: %{public}d", prevSession->GetMissionId());
8058         listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
8059     }
8060     if (currSession && !currSession->GetSessionInfo().isSystem_) {
8061         TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", currSession->GetMissionId());
8062         listenerController_->NotifySessionFocused(currSession->GetMissionId());
8063     }
8064 }
8065 
NotifyUnFocusedByMission(const sptr<SceneSession> & sceneSession)8066 void SceneSessionManager::NotifyUnFocusedByMission(const sptr<SceneSession>& sceneSession)
8067 {
8068     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
8069         TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", sceneSession->GetMissionId());
8070         listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
8071     }
8072 }
8073 
NotifyFocusedByMission(const sptr<SceneSession> & sceneSession)8074 void SceneSessionManager::NotifyFocusedByMission(const sptr<SceneSession>& sceneSession)
8075 {
8076     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
8077         TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", sceneSession->GetMissionId());
8078         listenerController_->NotifySessionFocused(sceneSession->GetMissionId());
8079     }
8080 }
8081 
MissionChanged(const sptr<SceneSession> & prevSession,const sptr<SceneSession> & currSession)8082 bool SceneSessionManager::MissionChanged(const sptr<SceneSession>& prevSession, const sptr<SceneSession>& currSession)
8083 {
8084     if (prevSession == nullptr && currSession == nullptr) {
8085         return false;
8086     }
8087     if (prevSession == nullptr || currSession == nullptr) {
8088         return true;
8089     }
8090     return prevSession->GetMissionId() != currSession->GetMissionId();
8091 }
8092 
GetAllSessionFocusInfo()8093 std::string SceneSessionManager::GetAllSessionFocusInfo()
8094 {
8095     std::ostringstream os;
8096     auto func = [&os](sptr<SceneSession> session) {
8097         if (session == nullptr) {
8098             TLOGNE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
8099             return false;
8100         }
8101         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
8102               ", focusable: " << session->GetFocusable() << ";";
8103         return false;
8104     };
8105     TraverseSessionTree(func, true);
8106     return os.str();
8107 }
8108 
UpdateFocus(int32_t persistentId,bool isFocused)8109 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
8110 {
8111     auto task = [this, persistentId, isFocused]() {
8112         // notify session and client
8113         auto sceneSession = GetSceneSession(persistentId);
8114         if (sceneSession == nullptr) {
8115             TLOGNE(WmsLogTag::WMS_FOCUS, "UpdateFocus could not find window, persistentId:%{public}d", persistentId);
8116             return WSError::WS_ERROR_INVALID_WINDOW;
8117         }
8118         TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
8119             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
8120         // focusId change
8121         auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8122         auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8123         if (isFocused) {
8124             SetFocusedSessionId(displayId, persistentId);
8125             UpdateBrightness(focusedSessionId);
8126             FocusIDChange(persistentId, sceneSession);
8127         } else if (persistentId == GetFocusedSessionId()) {
8128             SetFocusedSessionId(displayId, INVALID_SESSION_ID);
8129         }
8130         // notify window manager
8131         sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
8132             sceneSession->GetWindowId(),
8133             static_cast<DisplayId>(0),
8134             sceneSession->GetCallingPid(),
8135             sceneSession->GetCallingUid(),
8136             sceneSession->GetWindowType(),
8137             sceneSession->GetAbilityToken()
8138         );
8139         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
8140         WSError res = WSError::WS_OK;
8141         res = sceneSession->UpdateFocus(isFocused);
8142         if (res != WSError::WS_OK) {
8143             return res;
8144         }
8145         TLOGNI(WmsLogTag::WMS_FOCUS, "UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
8146               sceneSession->GetSessionInfo().isSystem_);
8147         if (!sceneSession->GetSessionInfo().isSystem_) {
8148             if (isFocused) {
8149                 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyFocused, id: %{public}d", sceneSession->GetPersistentId());
8150                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
8151             } else {
8152                 TLOGND(WmsLogTag::WMS_FOCUS, "NotifyUnFocused, id: %{public}d", sceneSession->GetPersistentId());
8153                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
8154             }
8155         }
8156         return WSError::WS_OK;
8157     };
8158 
8159     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
8160     return WSError::WS_OK;
8161 }
8162 
UpdateWindowMode(int32_t persistentId,int32_t windowMode)8163 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
8164 {
8165     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, mode: %{public}d", persistentId, windowMode);
8166     auto sceneSession = GetSceneSession(persistentId);
8167     if (sceneSession == nullptr) {
8168         TLOGE(WmsLogTag::DEFAULT, "could not find window, Id:%{public}d", persistentId);
8169         return WSError::WS_ERROR_INVALID_WINDOW;
8170     }
8171     WindowMode mode = static_cast<WindowMode>(windowMode);
8172     return sceneSession->UpdateWindowMode(mode);
8173 }
8174 
GetNormalSingleHandTransform() const8175 SingleHandTransform SceneSessionManager::GetNormalSingleHandTransform() const
8176 {
8177     return singleHandTransform_;
8178 }
8179 
GetSingleHandScreenInfo() const8180 SingleHandScreenInfo SceneSessionManager::GetSingleHandScreenInfo() const
8181 {
8182     return singleHandScreenInfo_;
8183 }
8184 
GetOriginRect() const8185 WSRect SceneSessionManager::GetOriginRect() const
8186 {
8187     return originRect_;
8188 }
8189 
GetSingleHandRect() const8190 WSRect SceneSessionManager::GetSingleHandRect() const
8191 {
8192     return singleHandRect_;
8193 }
8194 
NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo,WSRect originRect,WSRect singleHandRect)8195 void SceneSessionManager::NotifySingleHandInfoChange(SingleHandScreenInfo singleHandScreenInfo, WSRect originRect, WSRect singleHandRect)
8196 {
8197     const char* const funcName = __func__;
8198     taskScheduler_->PostAsyncTask([this, singleHandScreenInfo, originRect, singleHandRect, funcName] {
8199         if (!systemConfig_.IsPhoneWindow()) {
8200             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: only support phone", funcName);
8201             return;
8202         }
8203         int32_t displayWidth = 0;
8204         int32_t displayHeight = 0;
8205         ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
8206         if (!GetDisplaySizeById(defaultScreenId, displayWidth, displayHeight)) {
8207             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: get display size failed", funcName);
8208             return;
8209         }
8210         singleHandScreenInfo_ = singleHandScreenInfo;
8211         originRect_ = originRect;
8212         singleHandRect_ = singleHandRect;
8213         singleHandTransform_.posX = singleHandRect.posX_;
8214         singleHandTransform_.posY = singleHandRect.posY_;
8215         singleHandTransform_.scaleX = static_cast<float>(singleHandScreenInfo_.scaleRatio) / 100;
8216         singleHandTransform_.scaleY = singleHandTransform_.scaleX;
8217         {
8218             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8219             for (const auto& [_, sceneSession] : sceneSessionMap_) {
8220                 if (sceneSession == nullptr || !IsInDefaultScreen(sceneSession) ||
8221                     sceneSession->GetWindowName().find("OneHandModeBackground", 0) != std::string::npos) {
8222                     continue;
8223                 }
8224                 sceneSession->SetSingleHandModeFlag(true);
8225                 sceneSession->SetSingleHandTransform(singleHandTransform_);
8226                 sceneSession->NotifySingleHandTransformChange(singleHandTransform_);
8227             }
8228         }
8229         FlushWindowInfoToMMI();
8230     }, funcName);
8231 }
8232 
RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc && func)8233 void SceneSessionManager::RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc&& func)
8234 {
8235     getRSNodeByStringIDFunc_ = std::move(func);
8236 }
8237 
RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc && func)8238 void SceneSessionManager::RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc&& func)
8239 {
8240     setTopWindowBoundaryByIDFunc_ = std::move(func);
8241 }
8242 
RegisterSingleHandContainerNode(const std::string & stringId)8243 void SceneSessionManager::RegisterSingleHandContainerNode(const std::string& stringId)
8244 {
8245     if (getRSNodeByStringIDFunc_ == nullptr) {
8246         TLOGE(WmsLogTag::WMS_LAYOUT, "func is nullptr");
8247         return;
8248     }
8249     auto rsNode = getRSNodeByStringIDFunc_(stringId);
8250     if (rsNode == nullptr) {
8251         TLOGE(WmsLogTag::WMS_LAYOUT, "node is nullptr");
8252         return;
8253     }
8254     TLOGI(WmsLogTag::WMS_LAYOUT, "get OneHandModeBox node, id: %{public}" PRIu64, rsNode->GetId());
8255     setTopWindowBoundaryByIDFunc_(stringId);
8256     rsInterface_.SetWindowContainer(rsNode->GetId(), true);
8257 }
8258 
GetSingleHandCompatibleModeConfig() const8259 const SingleHandCompatibleModeConfig& SceneSessionManager::GetSingleHandCompatibleModeConfig() const
8260 {
8261     return singleHandCompatibleModeConfig_;
8262 }
8263 
8264 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)8265 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
8266     MMI::PointerEvent::PointerItem& pointerItem)
8267 {
8268     struct PointerEventData {
8269         double x;
8270         double y;
8271         uint64_t time;
8272     } pointerEventData = {
8273         .x = pointerItem.GetDisplayX(),
8274         .y = pointerItem.GetDisplayY(),
8275         .time = pointerEvent->GetActionTime()
8276     };
8277 
8278     const uint32_t MAX_HMAC_SIZE = 64;
8279     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
8280     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
8281     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
8282     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
8283         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
8284         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
8285     }
8286 }
8287 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
8288 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)8289 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
8290 {
8291     if (!pointerEvent) {
8292         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null");
8293         return WSError::WS_ERROR_NULLPTR;
8294     }
8295     MMI::PointerEvent::PointerItem pointerItem;
8296     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
8297         TLOGE(WmsLogTag::WMS_EVENT, "Failed to get pointerItem");
8298         return WSError::WS_ERROR_INVALID_PARAM;
8299     }
8300 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
8301     FillSecCompEnhanceData(pointerEvent, pointerItem);
8302 #endif
8303     TLOGI(WmsLogTag::WMS_EVENT, "eid=%{public}d,ac=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
8304         pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
8305     pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
8306     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
8307     return WSError::WS_OK;
8308 }
8309 
SetScreenLocked(const bool isScreenLocked)8310 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
8311 {
8312     taskScheduler_->PostTask([this, isScreenLocked] {
8313         isScreenLocked_ = isScreenLocked;
8314         DeleteStateDetectTask();
8315         NotifyPiPWindowVisibleChange(isScreenLocked);
8316     }, __func__);
8317 }
8318 
SetUserAuthPassed(bool isUserAuthPassed)8319 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
8320 {
8321     taskScheduler_->PostTask([this, isUserAuthPassed] {
8322         isUserAuthPassed_ = isUserAuthPassed;
8323     }, __func__);
8324 }
8325 
DeleteStateDetectTask()8326 void SceneSessionManager::DeleteStateDetectTask()
8327 {
8328     if (!IsScreenLocked()) {
8329         return;
8330     }
8331     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8332     for (auto iter : sceneSessionMap_) {
8333         auto& session = iter.second;
8334         if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
8335             taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
8336             DetectTaskInfo detectTaskInfo;
8337             session->SetDetectTaskInfo(detectTaskInfo);
8338         }
8339     }
8340 }
8341 
IsScreenLocked() const8342 bool SceneSessionManager::IsScreenLocked() const
8343 {
8344     return isScreenLocked_;
8345 }
8346 
IsUserAuthPassed() const8347 bool SceneSessionManager::IsUserAuthPassed() const
8348 {
8349     return isUserAuthPassed_;
8350 }
8351 
RegisterWindowChanged(const WindowChangedFunc & func)8352 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
8353 {
8354     WindowChangedFunc_ = func;
8355 }
8356 
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)8357 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
8358     const std::unordered_set<std::string>& privacyBundles)
8359 {
8360     bool needNotify = false;
8361     static int reSendTimes = MAX_RESEND_TIMES;
8362     std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
8363     do {
8364         if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
8365             TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
8366             needNotify = !privacyBundles.empty();
8367             break;
8368         }
8369         const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
8370         if (lastPrivacyBundles.size() != privacyBundles.size()) {
8371             TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
8372                   lastPrivacyBundles.size(), privacyBundles.size());
8373             needNotify = true;
8374             break;
8375         }
8376         for (const auto& bundle : lastPrivacyBundles) {
8377             if (privacyBundles.find(bundle) == privacyBundles.end()) {
8378                 needNotify = true;
8379                 break;
8380             }
8381         }
8382     } while (false);
8383 
8384     TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
8385           displayId, needNotify);
8386     if (needNotify) {
8387         reSendTimes = MAX_RESEND_TIMES;
8388         privacyBundleMap_[displayId] = privacyBundles;
8389     } else if (reSendTimes > 0) {
8390         needNotify = true;
8391         reSendTimes--;
8392         privacyBundleMap_[displayId] = privacyBundles;
8393     }
8394     return needNotify;
8395 }
8396 
UpdatePrivateStateAndNotify(uint32_t persistentId)8397 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
8398 {
8399     auto sceneSession = GetSceneSession(persistentId);
8400     if (sceneSession == nullptr) {
8401         TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid=%{public}u.", persistentId);
8402         return;
8403     }
8404 
8405     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8406     std::unordered_set<std::string> privacyBundleList;
8407     GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
8408     if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
8409         return;
8410     }
8411 
8412     std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
8413     ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
8414         !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
8415     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
8416     if (!bundleListForNotify.empty()) {
8417         TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
8418     }
8419     for (const auto& bundle : bundleListForNotify) {
8420         TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display=%{public}" PRIu64 ", bundle=%{public}s.",
8421               displayId, bundle.c_str());
8422     }
8423 }
8424 
UpdatePrivateStateAndNotifyForAllScreens()8425 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
8426 {
8427     auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
8428     for (auto& iter : screenProperties) {
8429         auto displayId = iter.first;
8430         std::unordered_set<std::string> privacyBundleList;
8431         GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
8432 
8433         ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
8434             !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
8435     }
8436 }
8437 
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)8438 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
8439     std::unordered_set<std::string>& privacyBundles)
8440 {
8441     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8442     for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
8443         if (sceneSession == nullptr) {
8444             TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid=%{public}d.", persistentId);
8445             continue;
8446         }
8447         auto sessionProperty = sceneSession->GetSessionProperty();
8448         auto currentDisplayId = sessionProperty->GetDisplayId();
8449         if (displayId != currentDisplayId) {
8450             continue;
8451         }
8452         bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8453                             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
8454         if (isForeground && sceneSession->GetParentSession() != nullptr) {
8455             isForeground = isForeground &&
8456                 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
8457                  sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
8458         }
8459         bool isPrivate = sessionProperty->GetPrivacyMode() ||
8460             sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
8461         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
8462         if ((isForeground || IsSystemWindowVisible) && isPrivate) {
8463             if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
8464                 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
8465             } else {
8466                 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "bundle name is empty, wid=%{public}d.", persistentId);
8467                 privacyBundles.insert(sceneSession->GetWindowName());
8468             }
8469         }
8470     }
8471 }
8472 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)8473 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
8474 {
8475     if (sceneSession == nullptr) {
8476         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8477         return;
8478     }
8479     sceneSession->SetSessionStateChangeNotifyManagerListener(
8480         [this](int32_t persistentId, const SessionState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
8481             OnSessionStateChange(persistentId, state);
8482         });
8483     TLOGD(WmsLogTag::DEFAULT, "success");
8484 }
8485 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)8486 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
8487 {
8488     if (sceneSession == nullptr) {
8489         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8490         return;
8491     }
8492     sceneSession->SetSessionInfoChangeNotifyManagerListener([this](int32_t persistentId) {
8493         NotifyWindowInfoChangeFromSession(persistentId);
8494     });
8495 }
8496 
RegisterDisplayIdChangedNotifyManagerFunc(const sptr<SceneSession> & sceneSession)8497 void SceneSessionManager::RegisterDisplayIdChangedNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
8498 {
8499     if (sceneSession == nullptr) {
8500         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
8501         return;
8502     }
8503     sceneSession->SetDisplayIdChangedNotifyManagerListener([this](int32_t persistentId, uint64_t displayId) {
8504         NotifyDisplayIdChanged(persistentId, displayId);
8505     });
8506 }
8507 
RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession> & sceneSession)8508 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
8509 {
8510     if (sceneSession == nullptr) {
8511         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8512         return;
8513     }
8514     sceneSession->SetRequestFocusStatusNotifyManagerListener(
8515         [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
8516             RequestFocusStatus(persistentId, isFocused, byForeground, reason);
8517         });
8518     TLOGD(WmsLogTag::DEFAULT, "success");
8519 }
8520 
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)8521 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
8522 {
8523     GetStateFromManagerFunc func = [this](const ManagerState key) {
8524         switch (key) {
8525             case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
8526                 return this->IsScreenLocked();
8527                 break;
8528             default:
8529                 return false;
8530                 break;
8531         }
8532     };
8533     if (sceneSession == nullptr) {
8534         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
8535         return;
8536     }
8537     sceneSession->SetGetStateFromManagerListener(func);
8538     TLOGD(WmsLogTag::DEFAULT, "success");
8539 }
8540 
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)8541 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
8542 {
8543     SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
8544         const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
8545         if (sceneSession == nullptr || property == nullptr) {
8546             TLOGNE(WmsLogTag::DEFAULT, "params is nullptr");
8547             return;
8548         }
8549         switch (action) {
8550             case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
8551                 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8552                                    sceneSession->keepScreenLock_);
8553                 break;
8554             case WSPropertyChangeAction::ACTION_UPDATE_VIEW_KEEP_SCREEN_ON:
8555                 HandleKeepScreenOn(sceneSession, property->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8556                                    sceneSession->viewKeepScreenLock_);
8557                 break;
8558             case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
8559             case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
8560             case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
8561             case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
8562             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
8563             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
8564             case WSPropertyChangeAction::ACTION_UPDATE_FOLLOW_SCREEN_CHANGE:
8565                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
8566                 break;
8567             case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
8568                 SetBrightness(sceneSession, property->GetBrightness());
8569                 break;
8570             case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
8571             case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
8572                 UpdatePrivateStateAndNotify(property->GetPersistentId());
8573                 break;
8574             case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
8575                 CheckAndNotifyWaterMarkChangedResult();
8576                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
8577                 break;
8578             case WSPropertyChangeAction::ACTION_UPDATE_MODE:
8579                 ProcessWindowModeType();
8580                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
8581                 break;
8582             case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
8583                 HandleHideNonSystemFloatingWindows(property, sceneSession);
8584                 break;
8585             case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
8586                 FlushWindowInfoToMMI();
8587                 break;
8588             default:
8589                 break;
8590         }
8591     };
8592     if (sceneSession != nullptr) {
8593         sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
8594     }
8595 }
8596 
OnSessionStateChange(int32_t persistentId,const SessionState & state)8597 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
8598     int32_t persistentId, const SessionState& state)
8599 {
8600     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
8601     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, state:%{public}u", persistentId, state);
8602     SceneSessionChangeInfo changeInfo {
8603         .persistentId_ = persistentId,
8604         .changeInfo_ = "Session state change to " + std::to_string(static_cast<uint32_t>(state)),
8605         .logTag_ = WmsLogTag::WMS_LIFE,
8606     };
8607     SessionChangeRecorder::GetInstance().RecordSceneSessionChange(RecordType::SESSION_STATE_RECORD, changeInfo);
8608     auto sceneSession = GetSceneSession(persistentId);
8609     if (sceneSession == nullptr) {
8610         TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
8611         return;
8612     }
8613     switch (state) {
8614         case SessionState::STATE_FOREGROUND:
8615             ProcessFocusWhenForeground(sceneSession);
8616             if (!IsSessionVisibleForeground(sceneSession)) {
8617                 sceneSession->SetPostProcessProperty(true);
8618                 break;
8619             }
8620             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
8621             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
8622             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8623                                sceneSession->keepScreenLock_);
8624             HandleKeepScreenOn(sceneSession, sceneSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8625                                sceneSession->viewKeepScreenLock_);
8626             UpdatePrivateStateAndNotify(persistentId);
8627             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8628                 ProcessSubSessionForeground(sceneSession);
8629             }
8630             break;
8631         case SessionState::STATE_BACKGROUND:
8632             NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
8633             RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
8634             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
8635             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
8636             HandleKeepScreenOn(sceneSession, false, WINDOW_SCREEN_LOCK_PREFIX, sceneSession->keepScreenLock_);
8637             HandleKeepScreenOn(sceneSession, false, VIEW_SCREEN_LOCK_PREFIX, sceneSession->viewKeepScreenLock_);
8638             UpdatePrivateStateAndNotify(persistentId);
8639             if (persistentId == brightnessSessionId_) {
8640                 auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8641                 auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8642                 UpdateBrightness(focusedSessionId);
8643             }
8644             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8645                 ProcessSubSessionBackground(sceneSession);
8646             }
8647             break;
8648         case SessionState::STATE_CONNECT:
8649             SetSessionSnapshotSkipForAppProcess(sceneSession);
8650             SetSessionSnapshotSkipForAppBundleName(sceneSession);
8651             SetSessionWatermarkForAppProcess(sceneSession);
8652             break;
8653         case SessionState::STATE_DISCONNECT:
8654             if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
8655                 RemoveProcessSnapshotSkip(sceneSession->GetCallingPid());
8656                 RemoveProcessWatermarkPid(sceneSession->GetCallingPid());
8657             }
8658             break;
8659         default:
8660             break;
8661     }
8662 }
8663 
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)8664 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
8665 {
8666     auto persistentId = sceneSession->GetPersistentId();
8667     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8668     auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
8669     if (focusGroup == nullptr) {
8670         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
8671         return;
8672     }
8673     bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
8674     bool needBlockNotifyUnfocusStatus = focusGroup->GetNeedBlockNotifyUnfocusStatus();
8675     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
8676         persistentId == focusGroup->GetFocusedSessionId()) {
8677         if (focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground()) {
8678             focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
8679             focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
8680             NotifyFocusStatus(sceneSession, true, focusGroup);
8681             sceneSession->NotifyHighlightChange(true);
8682         }
8683     } else if (!sceneSession->IsFocusedOnShow()) {
8684         if (IsSessionVisibleForeground(sceneSession)) {
8685             sceneSession->SetFocusedOnShow(true);
8686         }
8687     } else {
8688         if (Session::IsScbCoreEnabled()) {
8689             ProcessFocusWhenForegroundScbCore(sceneSession);
8690         } else {
8691             RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
8692         }
8693     }
8694 }
8695 
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)8696 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
8697 {
8698     if (sceneSession == nullptr) {
8699         TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
8700         return;
8701     }
8702     if (sceneSession->IsFocusableOnShow()) {
8703         if (IsSessionVisibleForeground(sceneSession)) {
8704             RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
8705         } else {
8706             PostProcessFocusState state = {true, true, true, FocusChangeReason::APP_FOREGROUND};
8707             sceneSession->SetPostProcessFocusState(state);
8708         }
8709     } else {
8710         TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
8711             sceneSession->GetPersistentId());
8712     }
8713 }
8714 
ProcessWindowModeType()8715 void SceneSessionManager::ProcessWindowModeType()
8716 {
8717     if (isScreenLocked_) {
8718         return;
8719     }
8720     NotifyRSSWindowModeTypeUpdate();
8721 }
8722 
IsSmallFoldProduct()8723 static bool IsSmallFoldProduct()
8724 {
8725     static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
8726     if (foldScreenType.empty()) {
8727         return false;
8728     }
8729     return foldScreenType[0] == SMALL_FOLD_PRODUCT_TYPE;
8730 }
8731 
IsInDefaultScreen(const sptr<SceneSession> & sceneSession)8732 bool SceneSessionManager::IsInDefaultScreen(const sptr<SceneSession>& sceneSession)
8733 {
8734     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
8735     return sceneSession->GetSessionProperty()->GetDisplayId() == defaultScreenId;
8736 }
8737 
IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession> & sceneSession,bool isSmallFold)8738 bool SceneSessionManager::IsNeedSkipWindowModeTypeCheck(const sptr<SceneSession>& sceneSession, bool isSmallFold)
8739 {
8740     if (sceneSession == nullptr ||
8741         !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
8742         !sceneSession->GetRSVisible() ||
8743         !sceneSession->IsSessionForeground()) {
8744         return true;
8745     }
8746     if (isSmallFold && !IsInDefaultScreen(sceneSession)) {
8747         return true;
8748     }
8749     return false;
8750 }
8751 
CheckWindowModeType()8752 WindowModeType SceneSessionManager::CheckWindowModeType()
8753 {
8754     bool inSplit = false;
8755     bool inFloating = false;
8756     bool fullScreen = false;
8757     bool isSmallFold = IsSmallFoldProduct();
8758     {
8759         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8760         for (const auto& session : sceneSessionMap_) {
8761             if (IsNeedSkipWindowModeTypeCheck(session.second, isSmallFold)) {
8762                 continue;
8763             }
8764             auto mode = session.second->GetWindowMode();
8765             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
8766                 inSplit = true;
8767             }
8768             if (mode == WindowMode::WINDOW_MODE_FLOATING) {
8769                 inFloating = true;
8770             }
8771             if (WindowHelper::IsFullScreenWindow(mode)) {
8772                 fullScreen = true;
8773             }
8774         }
8775     }
8776 
8777     WindowModeType type;
8778     if (inSplit) {
8779         if (inFloating) {
8780             type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
8781         } else {
8782             type = WindowModeType::WINDOW_MODE_SPLIT;
8783         }
8784     } else {
8785         if (inFloating) {
8786             if (fullScreen) {
8787                 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
8788             } else {
8789                 type = WindowModeType::WINDOW_MODE_FLOATING;
8790             }
8791         } else if (fullScreen) {
8792             type = WindowModeType::WINDOW_MODE_FULLSCREEN;
8793         } else {
8794             type = WindowModeType::WINDOW_MODE_OTHER;
8795         }
8796     }
8797     return type;
8798 }
8799 
NotifyRSSWindowModeTypeUpdate()8800 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
8801 {
8802     WindowModeType type = CheckWindowModeType();
8803     if (lastWindowModeType_ == type) {
8804         return;
8805     }
8806     lastWindowModeType_ = type;
8807     TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
8808         static_cast<uint8_t>(type));
8809     SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
8810 }
8811 
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)8812 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
8813 {
8814     if (sceneSession == nullptr) {
8815         TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
8816         return;
8817     }
8818     std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
8819     for (auto& subSession : sceneSession->GetSubSession()) {
8820         if (subSession == nullptr) {
8821             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
8822             continue;
8823         }
8824         if (!subSession->GetSubSession().empty()) {
8825             ProcessSubSessionForeground(subSession);
8826         }
8827         if (subSession->IsTopmost()) {
8828             modalVec.push_back(subSession);
8829             TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
8830             continue;
8831         }
8832         const auto& state = subSession->GetSessionState();
8833         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8834             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
8835             continue;
8836         }
8837         RequestSessionFocus(subSession->GetPersistentId(), true);
8838         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
8839         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8840                            subSession->keepScreenLock_);
8841         HandleKeepScreenOn(subSession, subSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8842                            subSession->viewKeepScreenLock_);
8843     }
8844 
8845     for (const auto& modal : modalVec) {
8846         if (modal == nullptr) {
8847             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
8848             continue;
8849         }
8850         const auto& state = modal->GetSessionState();
8851         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8852             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
8853             continue;
8854         }
8855         auto modalSession = GetSceneSession(modal->GetPersistentId());
8856         if (modalSession == nullptr) {
8857             TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
8858             continue;
8859         }
8860         NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
8861         auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8862         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
8863         if (focusGroup == nullptr) {
8864             TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
8865             return;
8866         }
8867         auto focusedSessionId = focusGroup->GetFocusedSessionId();
8868         bool needBlockNotifyFocusStatusUntilForeground = focusGroup->GetNeedBlockNotifyFocusStatusUntilForeground();
8869         if (modal->GetPersistentId() == focusedSessionId && needBlockNotifyFocusStatusUntilForeground) {
8870             focusGroup->SetNeedBlockNotifyFocusStatusUntilForeground(false);
8871             focusGroup->SetNeedBlockNotifyUnfocusStatus(false);
8872             NotifyFocusStatus(modalSession, true, focusGroup);
8873         }
8874         HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
8875                            modalSession->keepScreenLock_);
8876         HandleKeepScreenOn(modalSession, modalSession->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
8877                            modalSession->viewKeepScreenLock_);
8878     }
8879 }
8880 
ProcessModalTopmostRequestFocusImmediately(const sptr<SceneSession> & sceneSession)8881 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
8882 {
8883     // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
8884     sptr<SceneSession> mainSession = nullptr;
8885     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8886         mainSession = sceneSession;
8887     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
8888         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
8889     }
8890     if (mainSession == nullptr) {
8891         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
8892         return WSError::WS_DO_NOTHING;
8893     }
8894 
8895     std::vector<sptr<SceneSession>> topmostVec;
8896     for (auto subSession : mainSession->GetSubSession()) {
8897         if (subSession && subSession->IsTopmost()) {
8898             topmostVec.push_back(subSession);
8899         }
8900     }
8901     auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
8902     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8903     auto conditionFunc =  [this, focusedSessionId](const sptr<SceneSession>& iter) {
8904         return iter && iter->GetPersistentId() == focusedSessionId;
8905     };
8906     if (std::find_if(topmostVec.begin(), topmostVec.end(), std::move(conditionFunc)) != topmostVec.end()) {
8907         TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId);
8908         return WSError::WS_OK;
8909     }
8910     WSError ret = WSError::WS_DO_NOTHING;
8911     for (auto topmostSession : topmostVec) {
8912         if (topmostSession == nullptr) {
8913             continue;
8914         }
8915         // no need to consider order, since rule of zOrder
8916         if (RequestSessionFocusImmediately(topmostSession->GetPersistentId(), false) == WSError::WS_OK) {
8917             ret = WSError::WS_OK;
8918         }
8919     }
8920     return ret;
8921 }
8922 
ProcessSubWindowRequestFocusImmediately(const sptr<SceneSession> & sceneSession)8923 WSError SceneSessionManager::ProcessSubWindowRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
8924 {
8925     if (sceneSession == nullptr) {
8926         TLOGD(WmsLogTag::WMS_FOCUS, "session is null");
8927         return WSError::WS_DO_NOTHING;
8928     }
8929     std::vector<sptr<SceneSession>> subSessionVec = sceneSession->GetSubSession();
8930     if (subSessionVec.empty()) {
8931         TLOGD(WmsLogTag::WMS_FOCUS, "has no sub window");
8932         return WSError::WS_DO_NOTHING;
8933     }
8934     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
8935     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8936     auto conditionFunc =  [this, focusedSessionId](const sptr<SceneSession>& iter) {
8937         return iter && iter->GetPersistentId() == focusedSessionId;
8938     };
8939     if (std::find_if(subSessionVec.begin(), subSessionVec.end(), std::move(conditionFunc)) != subSessionVec.end()) {
8940         TLOGD(WmsLogTag::WMS_SUB, "sub window id: %{public}d has been focused!", focusedSessionId);
8941         return WSError::WS_OK;
8942     }
8943     WSError ret = WSError::WS_DO_NOTHING;
8944     for (auto session : subSessionVec) {
8945         if (session == nullptr) {
8946             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
8947             continue;
8948         }
8949         if (!IsSessionVisibleForeground(session)) {
8950             continue;
8951         }
8952         if (RequestSessionFocus(session->GetPersistentId(), true, FocusChangeReason::REQUEST_WITH_CHECK_SUB_WINDOW) ==
8953             WSError::WS_OK) {
8954             ret = WSError::WS_OK;
8955         }
8956     }
8957     return ret;
8958 }
8959 
ProcessDialogRequestFocusImmediately(const sptr<SceneSession> & sceneSession)8960 WSError SceneSessionManager::ProcessDialogRequestFocusImmediately(const sptr<SceneSession>& sceneSession)
8961 {
8962     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
8963     sptr<SceneSession> mainSession = nullptr;
8964     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8965         mainSession = sceneSession;
8966     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
8967         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
8968     }
8969     if (mainSession == nullptr) {
8970         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
8971         return WSError::WS_DO_NOTHING;
8972     }
8973     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
8974     auto displayId = mainSession->GetSessionProperty()->GetDisplayId();
8975     auto focusedSessionId = windowFocusController_->GetFocusedSessionId(displayId);
8976     auto conditionFunc =  [this, focusedSessionId](const sptr<Session>& iter) {
8977         return iter && iter->GetPersistentId() == focusedSessionId;
8978     };
8979     if (std::find_if(dialogVec.begin(), dialogVec.end(), std::move(conditionFunc)) != dialogVec.end()) {
8980         TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId);
8981         return WSError::WS_OK;
8982     }
8983     WSError ret = WSError::WS_DO_NOTHING;
8984     for (auto dialog : dialogVec) {
8985         if (dialog == nullptr) {
8986             continue;
8987         }
8988         // no need to consider order, since rule of zOrder
8989         if (RequestSessionFocusImmediately(dialog->GetPersistentId(), false) == WSError::WS_OK) {
8990             ret = WSError::WS_OK;
8991         }
8992     }
8993     return ret;
8994 }
8995 
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)8996 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
8997 {
8998     if (sceneSession == nullptr) {
8999         TLOGD(WmsLogTag::WMS_SUB, "session is nullptr");
9000         return;
9001     }
9002     for (auto& subSession : sceneSession->GetSubSession()) {
9003         if (subSession == nullptr) {
9004             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
9005             continue;
9006         }
9007         if (!subSession->GetSubSession().empty()) {
9008             ProcessSubSessionBackground(subSession);
9009         }
9010         const auto& state = subSession->GetSessionState();
9011         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9012             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
9013             continue;
9014         }
9015         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
9016         HandleKeepScreenOn(subSession, false, WINDOW_SCREEN_LOCK_PREFIX, subSession->keepScreenLock_);
9017         HandleKeepScreenOn(subSession, false, VIEW_SCREEN_LOCK_PREFIX, subSession->viewKeepScreenLock_);
9018         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
9019     }
9020     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
9021     for (const auto& dialog : dialogVec) {
9022         if (dialog == nullptr) {
9023             TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
9024             continue;
9025         }
9026         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
9027         if (dialogSession == nullptr) {
9028             TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
9029             continue;
9030         }
9031         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
9032         HandleKeepScreenOn(dialogSession, false, WINDOW_SCREEN_LOCK_PREFIX, dialogSession->keepScreenLock_);
9033         HandleKeepScreenOn(dialogSession, false, VIEW_SCREEN_LOCK_PREFIX, dialogSession->viewKeepScreenLock_);
9034         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
9035     }
9036     for (const auto& toastSession : sceneSession->GetToastSession()) {
9037         if (toastSession == nullptr) {
9038             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
9039             continue;
9040         }
9041         const auto& state = toastSession->GetSessionState();
9042         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9043             TLOGD(WmsLogTag::WMS_TOAST, "toast session is not active");
9044             continue;
9045         }
9046         NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
9047         HandleKeepScreenOn(toastSession, false, WINDOW_SCREEN_LOCK_PREFIX, toastSession->keepScreenLock_);
9048         HandleKeepScreenOn(toastSession, false, VIEW_SCREEN_LOCK_PREFIX, toastSession->viewKeepScreenLock_);
9049         UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
9050         toastSession->SetActive(false);
9051         toastSession->BackgroundTask();
9052     }
9053 }
9054 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)9055 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
9056     const sptr<WindowSessionProperty>& property)
9057 {
9058     if (sceneSession == nullptr) {
9059         TLOGD(WmsLogTag::DEFAULT, "session is nullptr");
9060         return WSError::WS_ERROR_NULLPTR;
9061     }
9062     auto sessionProperty = sceneSession->GetSessionProperty();
9063     uint32_t flags = property->GetWindowFlags();
9064     uint32_t oldFlags = sessionProperty->GetWindowFlags();
9065     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
9066          (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
9067         !property->GetSystemCalling()) {
9068         TLOGE(WmsLogTag::DEFAULT, "permission denied");
9069         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9070     }
9071     sessionProperty->SetWindowFlags(flags);
9072     CheckAndNotifyWaterMarkChangedResult();
9073     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
9074         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
9075     }
9076     TLOGI(WmsLogTag::DEFAULT, "set flags: %{public}u", flags);
9077     return WSError::WS_OK;
9078 }
9079 
CheckAndNotifyWaterMarkChangedResult()9080 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
9081 {
9082     bool currentWaterMarkShowState = false;
9083     {
9084         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9085         for (const auto& [_, session] : sceneSessionMap_) {
9086             if (!session) {
9087                 continue;
9088             }
9089             bool hasWaterMark = session->GetSessionProperty()->GetWindowFlags() &
9090                 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
9091             bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
9092             if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
9093                 currentWaterMarkShowState = true;
9094                 break;
9095             }
9096         }
9097         if (combinedExtWindowFlags_.waterMarkFlag) {
9098             TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
9099             currentWaterMarkShowState = true;
9100         }
9101     }
9102     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
9103         lastWaterMarkShowState_ = currentWaterMarkShowState;
9104         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
9105     }
9106 }
9107 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)9108 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
9109 {
9110     TLOGD(WmsLogTag::DEFAULT, "hasWaterMark: %{public}u", static_cast<uint32_t>(hasWaterMark));
9111     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
9112     return WSError::WS_OK;
9113 }
9114 
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const9115 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
9116 {
9117     if (!bundleMgr_) {
9118         TLOGE(WmsLogTag::DEFAULT, "bundle manager is nullptr.");
9119         return;
9120     }
9121 
9122     AAFwk::Want want;
9123     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
9124     auto uid = abilityInfo.uid;
9125     want.SetParam("uid", uid);
9126     bundleMgr_->ProcessPreload(want);
9127 }
9128 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)9129 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
9130 {
9131     auto sceneSession = GetSceneSession(persistentId);
9132     if (sceneSession == nullptr) {
9133         TLOGE(WmsLogTag::WMS_MAIN, " sceneSession is nullptr.");
9134         return;
9135     }
9136 
9137     const auto& sessionInfo = sceneSession->GetSessionInfo();
9138     if (IsAtomicServiceFreeInstall(sessionInfo)) {
9139         TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
9140             sceneSession->GetPersistentId(), sceneSession->GetWindowType());
9141         FillSessionInfo(sceneSession);
9142     }
9143     TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
9144         sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
9145         sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
9146     auto abilityInfo = sessionInfo.abilityInfo;
9147     if (abilityInfo == nullptr) {
9148         TLOGE(WmsLogTag::WMS_MAIN, " abilityInfo is null, Id: %{public}d", persistentId);
9149         return;
9150     }
9151 
9152     [this, persistentId] {
9153         auto task = [persistentId] {
9154             AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
9155         };
9156         TLOGNI(WmsLogTag::DEFAULT, "Post CompleteFirstFrameDrawing task. Id: %{public}d", persistentId);
9157         eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
9158     }();
9159 
9160     auto task = [this, abilityInfo, sceneSession, persistentId] {
9161         if (!sceneSession->GetSessionInfo().isSystem_ && !(abilityInfo->excludeFromMissions)) {
9162             TLOGND(WmsLogTag::WMS_PATTERN, "NotifyCreated, id: %{public}d", persistentId);
9163             listenerController_->NotifySessionLifecycleEvent(
9164                 ISessionLifecycleListener::SessionLifecycleEvent::CREATED, sceneSession->GetSessionInfo());
9165         }
9166         ProcessPreload(*abilityInfo);
9167     };
9168 
9169     if (sceneSession->GetLeashWinSurfaceNode()) {
9170         SetSkipSelfWhenShowOnVirtualScreen(sceneSession->GetLeashWinSurfaceNode()->GetId(),
9171             sceneSession->GetSkipSelfWhenShowOnVirtualScreen());
9172     }
9173     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
9174 }
9175 
NotifySessionMovedToFront(int32_t persistentId)9176 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
9177 {
9178     auto sceneSession = GetSceneSession(persistentId);
9179     if (sceneSession == nullptr) {
9180         TLOGE(WmsLogTag::DEFAULT, "session is invalid with %{public}d", persistentId);
9181         return;
9182     }
9183     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
9184            sceneSession->GetSessionInfo().isSystem_);
9185     if (!sceneSession->GetSessionInfo().isSystem_ &&
9186         sceneSession->GetSessionInfo().abilityInfo &&
9187         !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
9188         listenerController_->NotifySessionMovedToFront(persistentId);
9189     }
9190 }
9191 
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)9192 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
9193 {
9194     TLOGI(WmsLogTag::WMS_MAIN, "in");
9195     const char* const where = __func__;
9196     auto task = [this, &token, &label, where]() {
9197         auto sceneSession = FindSessionByToken(token);
9198         if (sceneSession == nullptr) {
9199             TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
9200             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
9201         }
9202         sceneSession->SetSessionLabel(label);
9203         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
9204             where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
9205         if (!sceneSession->GetSessionInfo().isSystem_) {
9206             TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
9207             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
9208         }
9209         return WSError::WS_OK;
9210     };
9211     return taskScheduler_->PostSyncTask(task, where);
9212 }
9213 
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)9214 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
9215     const std::shared_ptr<Media::PixelMap>& icon)
9216 {
9217     TLOGI(WmsLogTag::WMS_MAIN, "in");
9218     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9219         TLOGE(WmsLogTag::WMS_MAIN, "The caller is not system-app, can not use system-api");
9220         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9221     }
9222     const char* const where = __func__;
9223     auto task = [this, &token, &icon, where]() {
9224         auto sceneSession = FindSessionByToken(token);
9225         if (sceneSession == nullptr) {
9226             TLOGNE(WmsLogTag::WMS_MAIN, "fail to find session by token");
9227             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
9228         }
9229         sceneSession->SetSessionIcon(icon);
9230         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d, system: %{public}d",
9231             where, sceneSession->GetPersistentId(), sceneSession->GetSessionInfo().isSystem_);
9232         if (!sceneSession->GetSessionInfo().isSystem_ &&
9233             sceneSession->GetSessionInfo().abilityInfo &&
9234             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
9235             TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id: %{public}d", where, sceneSession->GetPersistentId());
9236             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
9237         }
9238         return WSError::WS_OK;
9239     };
9240     return taskScheduler_->PostSyncTask(task, where);
9241 }
9242 
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)9243 WSError SceneSessionManager::IsValidSessionIds(
9244     const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
9245 {
9246     TLOGI(WmsLogTag::DEFAULT, "in");
9247     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9248     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
9249         auto search = sceneSessionMap_.find(sessionIds.at(i));
9250         if (search == sceneSessionMap_.end() || search->second == nullptr) {
9251             results.push_back(false);
9252             continue;
9253         }
9254         results.push_back(true);
9255     }
9256     return WSError::WS_OK;
9257 }
9258 
RegisterSessionListener(const sptr<ISessionListener> & listener)9259 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
9260 {
9261     TLOGI(WmsLogTag::DEFAULT, "in");
9262     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9263         TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
9264         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9265     }
9266     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9267         TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
9268         return WSError::WS_ERROR_INVALID_PERMISSION;
9269     }
9270     auto task = [this, &listener] {
9271         WSError ret = listenerController_->AddSessionListener(listener);
9272         // app continue report for distributed scheduled service
9273         SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
9274             static_cast<int32_t>(ret));
9275         return ret;
9276     };
9277     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
9278 }
9279 
UnRegisterSessionListener(const sptr<ISessionListener> & listener)9280 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
9281 {
9282     TLOGI(WmsLogTag::DEFAULT, "in");
9283     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9284         TLOGE(WmsLogTag::DEFAULT, "not system-app, can not use system-api");
9285         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9286     }
9287     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9288         TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
9289         return WSError::WS_ERROR_INVALID_PERMISSION;
9290     }
9291     auto task = [this, &listener] {
9292         listenerController_->DelSessionListener(listener);
9293         return WSError::WS_OK;
9294     };
9295     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
9296 }
9297 
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)9298 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
9299                                              std::vector<SessionInfoBean>& sessionInfos)
9300 {
9301     TLOGI(WmsLogTag::DEFAULT, "num max %{public}d", numMax);
9302     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9303         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
9304         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9305     }
9306     if (!SessionPermission::VerifySessionPermission()) {
9307         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
9308         return WSError::WS_ERROR_INVALID_PERMISSION;
9309     }
9310     auto task = [this, &deviceId, numMax, &sessionInfos]() {
9311         if (CheckIsRemote(deviceId)) {
9312             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
9313             if (ret != ERR_OK) {
9314                 return WSError::WS_ERROR_INVALID_PARAM;
9315             } else {
9316                 return WSError::WS_OK;
9317             }
9318         }
9319         std::map<int32_t, sptr<SceneSession>>::iterator iter;
9320         std::vector<sptr<SceneSession>> sceneSessionInfos;
9321         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9322         for (const auto& [_, sceneSession] : sceneSessionMap_) {
9323             if (sceneSession == nullptr) {
9324                 TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
9325                 continue;
9326             }
9327             const auto& sessionInfo = sceneSession->GetSessionInfo();
9328             if (sessionInfo.isSystem_) {
9329                 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
9330                 continue;
9331             }
9332             auto want = sessionInfo.want;
9333             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
9334                 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
9335                     "or want bundleName is empty", sceneSession->GetPersistentId());
9336                 continue;
9337             }
9338             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
9339                 break;
9340             }
9341             TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfos session: %{public}d, bundleName:%{public}s",
9342                 sceneSession->GetPersistentId(), sessionInfo.bundleName_.c_str());
9343             sceneSessionInfos.emplace_back(sceneSession);
9344         }
9345         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
9346     };
9347     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
9348 }
9349 
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)9350 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
9351 {
9352     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
9353     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
9354         TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
9355         return WSError::WS_ERROR_INVALID_PERMISSION;
9356     }
9357     if (pid < 0) {
9358         return WSError::WS_ERROR_INVALID_PARAM;
9359     }
9360     auto task = [this, pid, &windowStates] {
9361         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9362         for (const auto& [_, sceneSession] : sceneSessionMap_) {
9363             if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
9364                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9365                 MainWindowState windowState;
9366                 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
9367                 windowState.isVisible_ = sceneSession->GetRSVisible();
9368                 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
9369                 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
9370                 windowStates.emplace_back(windowState);
9371             }
9372         }
9373         return WSError::WS_OK;
9374     };
9375     return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
9376 }
9377 
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)9378 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
9379                                                std::vector<SessionInfoBean>& sessionInfos)
9380 {
9381     TLOGI(WmsLogTag::DEFAULT, "begin");
9382     int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
9383     if (result != ERR_OK) {
9384         TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
9385         return result;
9386     }
9387     return ERR_OK;
9388 }
9389 
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)9390 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
9391                                             int32_t persistentId, SessionInfoBean& sessionInfo)
9392 {
9393     TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
9394     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9395         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
9396         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9397     }
9398     if (!SessionPermission::VerifySessionPermission()) {
9399         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
9400         return WSError::WS_ERROR_INVALID_PERMISSION;
9401     }
9402     return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &sessionInfo]() {
9403         if (CheckIsRemote(deviceId)) {
9404             if (GetRemoteSessionInfo(deviceId, persistentId, sessionInfo) != ERR_OK) {
9405                 return WSError::WS_ERROR_INVALID_PARAM;
9406             } else {
9407                 return WSError::WS_OK;
9408             }
9409         }
9410 
9411         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9412         if (auto iter = sceneSessionMap_.find(persistentId); iter != sceneSessionMap_.end()) {
9413             auto sceneSession = iter->second;
9414             if (sceneSession == nullptr) {
9415                 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d is nullptr", persistentId);
9416                 return WSError::WS_ERROR_INVALID_PARAM;
9417             }
9418             const auto& sceneSessionInfo = sceneSession->GetSessionInfo();
9419             if (sceneSessionInfo.isSystem_) {
9420                 TLOGND(WmsLogTag::WMS_LIFE, "sessionId: %{public}d  isSystemScene", persistentId);
9421                 return WSError::WS_ERROR_INVALID_PARAM;
9422             }
9423             auto want = sceneSessionInfo.want;
9424             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
9425                 want->GetElement().GetBundleName().empty()) {
9426                 TLOGNE(WmsLogTag::WMS_LIFE, "session: %{public}d, want is null or bundleName is empty "
9427                     "or want bundleName is empty", persistentId);
9428                 return WSError::WS_ERROR_INTERNAL_ERROR;
9429             }
9430             TLOGND(WmsLogTag::WMS_LIFE, "GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
9431                 sceneSessionInfo.bundleName_.c_str());
9432             return SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
9433         } else {
9434             TLOGNW(WmsLogTag::WMS_LIFE, "sessionId: %{public}d not found", persistentId);
9435             return WSError::WS_ERROR_INVALID_PARAM;
9436         }
9437     }, __func__);
9438 }
9439 
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)9440 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
9441     SessionInfoBean& sessionInfo)
9442 {
9443     TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
9444         continueSessionId.c_str());
9445     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9446         TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
9447         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9448     }
9449     if (!SessionPermission::VerifySessionPermission()) {
9450         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
9451         return WSError::WS_ERROR_INVALID_PERMISSION;
9452     }
9453     return taskScheduler_->PostSyncTask([this, continueSessionId, &sessionInfo]() {
9454         WSError ret = WSError::WS_ERROR_INVALID_SESSION;
9455         {
9456             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9457             for (const auto& [_, sceneSession] : sceneSessionMap_) {
9458                 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
9459                     ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
9460                     break;
9461                 }
9462             }
9463         }
9464 
9465         TLOGNI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
9466         // app continue report for distributed scheduled service
9467         SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
9468             static_cast<int32_t>(ret));
9469         return ret;
9470     }, __func__);
9471 }
9472 
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)9473 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
9474                                               int32_t persistentId, SessionInfoBean& sessionInfo)
9475 {
9476     TLOGI(WmsLogTag::DEFAULT, "in");
9477     std::vector<SessionInfoBean> sessionVector;
9478     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
9479     if (result != ERR_OK) {
9480         return result;
9481     }
9482     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
9483         if (iter->id == persistentId) {
9484             sessionInfo = *iter;
9485             return ERR_OK;
9486         }
9487     }
9488     TLOGW(WmsLogTag::DEFAULT, "missionId not found");
9489     return ERR_INVALID_VALUE;
9490 }
9491 
CheckIsRemote(const std::string & deviceId)9492 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
9493 {
9494     if (deviceId.empty()) {
9495         TLOGI(WmsLogTag::DEFAULT, "empty");
9496         return false;
9497     }
9498     std::string localDeviceId;
9499     if (!GetLocalDeviceId(localDeviceId)) {
9500         TLOGE(WmsLogTag::DEFAULT, "GetLocalDeviceId failed");
9501         return false;
9502     }
9503     if (localDeviceId == deviceId) {
9504         TLOGI(WmsLogTag::DEFAULT, "deviceId is local.");
9505         return false;
9506     }
9507     TLOGD(WmsLogTag::DEFAULT, "Checked deviceId=%{public}s", AnonymizeDeviceId(deviceId).c_str());
9508     return true;
9509 }
9510 
GetLocalDeviceId(std::string & localDeviceId)9511 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
9512 {
9513     auto localNode = std::make_unique<NodeBasicInfo>();
9514     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
9515     if (errCode != ERR_OK) {
9516         TLOGE(WmsLogTag::DEFAULT, "GetLocalNodeDeviceInfo errCode=%{public}d", errCode);
9517         return false;
9518     }
9519     if (localNode != nullptr) {
9520         localDeviceId = localNode->networkId;
9521         TLOGD(WmsLogTag::DEFAULT, "get local deviceId, deviceId=%{public}s", AnonymizeDeviceId(localDeviceId).c_str());
9522         return true;
9523     }
9524     TLOGE(WmsLogTag::DEFAULT, "localDeviceId null");
9525     return false;
9526 }
9527 
AnonymizeDeviceId(const std::string & deviceId)9528 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
9529 {
9530     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
9531         return EMPTY_DEVICE_ID;
9532     }
9533     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
9534     anonDeviceId.append("******");
9535     return anonDeviceId;
9536 }
9537 
DumpSessionAll(std::vector<std::string> & infos)9538 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
9539 {
9540     TLOGI(WmsLogTag::DEFAULT, "in.");
9541     if (!SessionPermission::IsSystemCalling()) {
9542         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
9543         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9544     }
9545 
9546     return taskScheduler_->PostSyncTask([this, &infos]() {
9547         infos.push_back("User ID #" + std::to_string(currentUserId_));
9548         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9549         for (const auto& [_, session] : sceneSessionMap_) {
9550             if (session) {
9551                 session->DumpSessionInfo(infos);
9552             }
9553         }
9554         return WSError::WS_OK;
9555     }, __func__);
9556 }
9557 
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)9558 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
9559 {
9560     TLOGI(WmsLogTag::DEFAULT, "id %{public}d", persistentId);
9561     if (!SessionPermission::IsSystemCalling()) {
9562         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
9563         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9564     }
9565 
9566     return taskScheduler_->PostSyncTask([this, persistentId, &infos]() {
9567         infos.push_back("User ID #" + std::to_string(currentUserId_));
9568         auto session = GetSceneSession(persistentId);
9569         if (session) {
9570             session->DumpSessionInfo(infos);
9571         } else {
9572             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
9573         }
9574         return WSError::WS_OK;
9575     }, __func__);
9576 }
9577 
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)9578 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
9579     const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
9580 {
9581     if (bundleMgr_ == nullptr) {
9582         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
9583         return WSError::WS_ERROR_NULLPTR;
9584     }
9585     const auto& elementName = want.GetElement();
9586     int32_t ret{0};
9587     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
9588         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
9589         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
9590         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
9591         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
9592         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
9593     std::vector<AppExecFwk::BundleInfo> bundleInfos;
9594     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
9595         TLOGD(WmsLogTag::DEFAULT, "want is empty queryAllAbilityInfos");
9596         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
9597         if (ret) {
9598             TLOGE(WmsLogTag::DEFAULT, "Query all ability infos from BMS failed!");
9599             return WSError::WS_ERROR_INVALID_PARAM;
9600         }
9601     } else if (!elementName.GetBundleName().empty()) {
9602         AppExecFwk::BundleInfo bundleInfo;
9603         TLOGD(WmsLogTag::DEFAULT, "bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
9604         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
9605         if (ret) {
9606             TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed!");
9607             return WSError::WS_ERROR_INVALID_PARAM;
9608         }
9609         bundleInfos.push_back(bundleInfo);
9610     } else {
9611         TLOGE(WmsLogTag::DEFAULT, "invalid want:%{public}s", want.ToString().c_str());
9612         return WSError::WS_ERROR_INVALID_PARAM;
9613     }
9614     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos, userId);
9615 }
9616 
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)9617 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
9618     const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
9619 {
9620     if (bundleMgr_ == nullptr) {
9621         TLOGE(WmsLogTag::WMS_RECOVER, "bundleMgr is nullptr");
9622         return WSError::WS_ERROR_NULLPTR;
9623     }
9624     if (bundleNames.empty()) {
9625         TLOGE(WmsLogTag::WMS_RECOVER, "bundleNames is empty");
9626         return WSError::WS_ERROR_INVALID_PARAM;
9627     }
9628     auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
9629                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
9630                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
9631                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
9632                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
9633                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
9634     std::vector<AppExecFwk::BundleInfo> bundleInfos;
9635     auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
9636     if (ret) {
9637         TLOGE(WmsLogTag::WMS_RECOVER, "Query batch ability infos from BMS failed!");
9638         return WSError::WS_ERROR_INVALID_PARAM;
9639     }
9640     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos, userId);
9641 }
9642 
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)9643 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
9644     const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
9645 {
9646     if (bundleMgr_ == nullptr) {
9647         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
9648         return WSError::WS_ERROR_NULLPTR;
9649     }
9650     auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
9651         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
9652         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
9653         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
9654         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
9655         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
9656     AppExecFwk::BundleInfo bundleInfo;
9657     if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
9658         TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
9659         return WSError::WS_ERROR_INVALID_PARAM;
9660     }
9661     auto& hapModulesList = bundleInfo.hapModuleInfos;
9662     if (hapModulesList.empty()) {
9663         TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
9664         return WSError::WS_ERROR_INVALID_PARAM;
9665     }
9666     auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
9667     for (auto& hapModule : hapModulesList) {
9668         bool isModuleAbilityHook = false;
9669         if (!hapModule.abilitySrcEntryDelegator.empty() && !hapModule.abilityStageSrcEntryDelegator.empty()) {
9670             isModuleAbilityHook = true;
9671         }
9672         auto& abilityInfoList = hapModule.abilityInfos;
9673         for (auto& abilityInfo : abilityInfoList) {
9674             abilityInfo.windowModes = ExtractSupportWindowModeFromMetaData(
9675                 std::make_shared<OHOS::AppExecFwk::AbilityInfo>(abilityInfo));
9676             if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
9677                 scbAbilityInfo.abilityInfo_ = abilityInfo;
9678                 scbAbilityInfo.sdkVersion_ = sdkVersion;
9679                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
9680                 scbAbilityInfo.isAbilityHook_ = isModuleAbilityHook;
9681                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
9682                 scbAbilityInfo.isForceRotate_ = bundleInfo.applicationInfo.isForceRotate;
9683                 return WSError::WS_OK;
9684             }
9685         }
9686     }
9687     TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
9688     return WSError::WS_ERROR_INVALID_PARAM;
9689 }
9690 
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos,int32_t userId)9691 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
9692     std::vector<SCBAbilityInfo>& scbAbilityInfos, int32_t userId)
9693 {
9694     if (bundleInfos.empty()) {
9695         TLOGE(WmsLogTag::DEFAULT, "bundleInfos is empty");
9696         return WSError::WS_ERROR_INVALID_PARAM;
9697     }
9698     std::vector<AppExecFwk::BundleInfo> collaboratorBundleInfos;
9699     for (auto& bundleInfo : bundleInfos) {
9700         auto& hapModulesList = bundleInfo.hapModuleInfos;
9701         auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
9702         if (hapModulesList.empty()) {
9703             TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty");
9704             continue;
9705         }
9706         if (WindowHelper::IsNumber(bundleInfo.applicationInfo.codePath) &&
9707             CheckCollaboratorType(std::stoi(bundleInfo.applicationInfo.codePath))) {
9708             collaboratorBundleInfos.emplace_back(bundleInfo);
9709             continue;
9710         }
9711         for (auto& hapModule : hapModulesList) {
9712             auto& abilityInfoList = hapModule.abilityInfos;
9713             bool isModuleAbilityHook = false;
9714             if (!hapModule.abilitySrcEntryDelegator.empty() && !hapModule.abilityStageSrcEntryDelegator.empty()) {
9715                 isModuleAbilityHook = true;
9716             }
9717             for (auto& abilityInfo : abilityInfoList) {
9718                 SCBAbilityInfo scbAbilityInfo;
9719                 scbAbilityInfo.abilityInfo_ = abilityInfo;
9720                 scbAbilityInfo.abilityInfo_.windowModes = ExtractSupportWindowModeFromMetaData(
9721                     std::make_shared<OHOS::AppExecFwk::AbilityInfo>(abilityInfo));
9722                 scbAbilityInfo.sdkVersion_ = sdkVersion;
9723                 scbAbilityInfo.isAbilityHook_ = isModuleAbilityHook;
9724                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
9725                 scbAbilityInfos.push_back(scbAbilityInfo);
9726             }
9727         }
9728     }
9729     GetCollaboratorAbilityInfos(collaboratorBundleInfos, scbAbilityInfos, userId);
9730     return WSError::WS_OK;
9731 }
9732 
GetCollaboratorAbilityInfos(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos,int32_t userId)9733 void SceneSessionManager::GetCollaboratorAbilityInfos(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
9734     std::vector<SCBAbilityInfo>& scbAbilityInfos, int32_t userId)
9735 {
9736     if (bundleInfos.empty()) {
9737         TLOGD(WmsLogTag::DEFAULT, "bundleInfos is empty");
9738         return;
9739     }
9740     std::vector<AppExecFwk::AbilityInfo> launcherAbilityInfos;
9741     AAFwk::Want want;
9742     want.SetAction(AAFwk::Want::ACTION_HOME);
9743     want.AddEntity(AAFwk::Want::ENTITY_HOME);
9744     if (!bundleMgr_ || bundleMgr_->QueryLauncherAbilityInfos(want, userId, launcherAbilityInfos) != ERR_OK) {
9745         TLOGE(WmsLogTag::DEFAULT, "Query launcher ability infos from BMS failed!");
9746         return;
9747     }
9748     std::unordered_map<std::string, AppExecFwk::AbilityInfo> abilityInfoMap;
9749     for (auto& abilityInfo : launcherAbilityInfos) {
9750         abilityInfoMap.emplace(abilityInfo.bundleName, abilityInfo);
9751     }
9752     for (auto& bundleInfo : bundleInfos) {
9753         AppExecFwk::AbilityInfo abilityInfo;
9754         auto& hapModulesList = bundleInfo.hapModuleInfos;
9755         auto iter = abilityInfoMap.find(bundleInfo.name);
9756         if (iter == abilityInfoMap.end()) {
9757             TLOGW(WmsLogTag::DEFAULT, "launcher ability not found, bundle:%{public}s", bundleInfo.name.c_str());
9758             auto hapModuleListIter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
9759                 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
9760             if (hapModuleListIter != hapModulesList.end()) {
9761                 abilityInfo = hapModuleListIter->abilityInfos[0];
9762             } else {
9763                 continue;
9764             }
9765         } else {
9766             if (!AbilityInfoManager::FindAbilityInfo(
9767                 bundleInfo, iter->second.moduleName, iter->second.name, abilityInfo)) {
9768                 continue;
9769             }
9770         }
9771         SCBAbilityInfo scbAbilityInfo;
9772         scbAbilityInfo.abilityInfo_ = abilityInfo;
9773         scbAbilityInfo.sdkVersion_ = bundleInfo.targetVersion % 100; // %100 to get the real version
9774         scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
9775         GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
9776         scbAbilityInfo.isForceRotate_ = bundleInfo.applicationInfo.isForceRotate;
9777         scbAbilityInfos.push_back(scbAbilityInfo);
9778     }
9779 }
9780 
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)9781 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
9782 {
9783     if (abilityInfo.orientationId == 0) {
9784         return;
9785     }
9786     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
9787     if (resConfig == nullptr) {
9788         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
9789         return;
9790     }
9791     std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
9792         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
9793     if (resourceMgr == nullptr) {
9794         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
9795         return;
9796     }
9797     std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
9798     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
9799         TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
9800     }
9801     std::string orientation;
9802     auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
9803     if (ret != Global::Resource::RState::SUCCESS) {
9804         TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
9805             static_cast<int32_t>(ret), abilityInfo.orientationId);
9806         return;
9807     }
9808     if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
9809         TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
9810         return;
9811     }
9812     abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
9813 }
9814 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)9815 WSError SceneSessionManager::TerminateSessionNew(
9816     const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
9817 {
9818     if (info == nullptr) {
9819         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
9820         return WSError::WS_ERROR_INVALID_PARAM;
9821     }
9822     TLOGI(WmsLogTag::WMS_LIFE,
9823         "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
9824         info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
9825     int32_t callingPid = IPCSkeleton::GetCallingPid();
9826     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
9827     auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
9828         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
9829         if (sceneSession == nullptr) {
9830             TLOGNE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
9831             return WSError::WS_ERROR_INVALID_PARAM;
9832         }
9833         const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
9834         if (!pidCheck &&
9835             !SessionPermission::VerifyPermissionByCallerToken(callerToken,
9836                 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9837             TLOGNE(WmsLogTag::WMS_LIFE,
9838                 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
9839                 sceneSession->GetCallingPid(), callingPid);
9840             return WSError::WS_ERROR_INVALID_PERMISSION;
9841         }
9842         WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
9843         return errCode;
9844     };
9845     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
9846 }
9847 
SetVmaCacheStatus(bool flag)9848 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
9849 {
9850     TLOGI(WmsLogTag::DEFAULT, "flag: %{public}d", flag);
9851     RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
9852     return WSError::WS_OK;
9853 }
9854 
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)9855 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
9856                                                 SessionSnapshot& snapshot, bool isLowResolution)
9857 {
9858     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
9859     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9860         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
9861         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9862     }
9863     if (!SessionPermission::VerifySessionPermission()) {
9864         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted");
9865         return WSError::WS_ERROR_INVALID_PERMISSION;
9866     }
9867     return taskScheduler_->PostSyncTask([this, &deviceId, persistentId, &snapshot, isLowResolution]() {
9868         if (CheckIsRemote(deviceId)) {
9869             if (GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot) != ERR_OK) {
9870                 return WSError::WS_ERROR_INVALID_PARAM;
9871             } else {
9872                 return WSError::WS_OK;
9873             }
9874         }
9875         auto sceneSession = GetSceneSession(persistentId);
9876         if (!sceneSession) {
9877             TLOGNE(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
9878             return WSError::WS_ERROR_INVALID_PARAM;
9879         }
9880         const auto& sessionInfo = sceneSession->GetSessionInfo();
9881         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
9882             TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
9883                    sceneSession->GetPersistentId());
9884         }
9885         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
9886         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
9887         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
9888         if (auto oriSnapshot = sceneSession->Snapshot()) {
9889             if (isLowResolution) {
9890                 OHOS::Media::InitializationOptions options;
9891                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
9892                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
9893                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
9894                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
9895             } else {
9896                 snapshot.snapshot = oriSnapshot;
9897             }
9898         }
9899         return WSError::WS_OK;
9900     }, __func__);
9901 }
9902 
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)9903 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
9904 {
9905     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
9906         TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
9907         return WMError::WM_ERROR_NOT_SYSTEM_APP;
9908     }
9909     return taskScheduler_->PostSyncTask([this, persistentId, &snapshot]() {
9910         auto sceneSession = GetSceneSession(persistentId);
9911         if (!sceneSession) {
9912             TLOGNW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
9913             return WMError::WM_ERROR_INVALID_PARAM;
9914         }
9915         const auto& sessionInfo = sceneSession->GetSessionInfo();
9916         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
9917             TLOGNW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
9918                 sceneSession->GetPersistentId());
9919         }
9920         snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
9921         snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
9922         snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
9923         float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
9924         if (auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale, false)) {
9925             if (sceneSession->GetFloatingScale() > 1.0f) {
9926                 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
9927             }
9928             snapshot.snapshot = oriSnapshot;
9929             TLOGNI(WmsLogTag::WMS_SYSTEM, "snapshot WxH=%{public}dx%{public}d",
9930                 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
9931             return WMError::WM_OK;
9932         }
9933         return WMError::WM_ERROR_NULLPTR;
9934     }, __func__);
9935 }
9936 
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)9937 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
9938 {
9939     if (!SessionPermission::IsSACalling()) {
9940         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Permission denied!");
9941         return WSError::WS_ERROR_INVALID_PERMISSION;
9942     }
9943     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "PersistentId=%{public}d", persistentId);
9944     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
9945     if (sceneSession == nullptr) {
9946         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sceneSession is nullptr");
9947         return WSError::WS_ERROR_NULLPTR;
9948     }
9949     return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
9950 }
9951 
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)9952 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
9953                                                       AAFwk::MissionSnapshot& sessionSnapshot)
9954 {
9955     TLOGI(WmsLogTag::DEFAULT, "begin");
9956     int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
9957         sessionId, sessionSnapshot);
9958     if (result != ERR_OK) {
9959         TLOGE(WmsLogTag::DEFAULT, "failed, result=%{public}d", result);
9960         return result;
9961     }
9962     return ERR_OK;
9963 }
9964 
GetCollaboratorByType(int32_t collaboratorType)9965 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
9966 {
9967     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
9968     std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
9969     auto iter = collaboratorMap_.find(collaboratorType);
9970     if (iter == collaboratorMap_.end()) {
9971         TLOGE(WmsLogTag::WMS_MAIN, "Fail to found collaborator with type: %{public}d", collaboratorType);
9972         return collaborator;
9973     }
9974     collaborator = iter->second;
9975     if (collaborator == nullptr) {
9976         TLOGE(WmsLogTag::WMS_MAIN, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
9977     }
9978     return collaborator;
9979 }
9980 
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession,int32_t requestId)9981 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession, int32_t requestId)
9982 {
9983     const char* const where = __func__;
9984     auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
9985         requestId, where]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
9986         auto sceneSession = weakSceneSession.promote();
9987         if (sceneSession == nullptr) {
9988             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is nullptr", where);
9989             return WSError::WS_ERROR_NULLPTR;
9990         }
9991         auto persistentId = sceneSession->GetPersistentId();
9992         if (!GetSceneSession(persistentId)) {
9993             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s: session is invalid, id:%{public}d", where, persistentId);
9994             return WSError::WS_ERROR_INVALID_SESSION;
9995         }
9996         const auto& sessionInfo = sceneSession->GetSessionInfo();
9997         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: state:%{public}d, id:%{public}d",
9998             where, sessionInfo.callState_, persistentId);
9999         auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession, requestId);
10000         bool isColdStart = false;
10001         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
10002         CloseAllFd(sessionInfo.want);
10003         if (isColdStart) {
10004             TLOGNI(WmsLogTag::WMS_MAIN, "Cold start, identityToken:%{public}s, bundleName:%{public}s",
10005                 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
10006             sceneSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
10007             sceneSession->ResetSessionConnectState();
10008             sceneSession->UpdatePrivacyModeControlInfo();
10009         }
10010         return WSError::WS_OK;
10011     };
10012     std::string taskName = "RequestSceneSessionByCall:PID:" +
10013         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
10014     taskScheduler_->PostAsyncTask(task, taskName);
10015     return WSError::WS_OK;
10016 }
10017 
StartAbilityBySpecified(const SessionInfo & sessionInfo)10018 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
10019 {
10020     const char* const where = __func__;
10021     ffrtQueueHelper_->SubmitTask([this, sessionInfo, where] {
10022         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: bundleName: %{public}s, "
10023             "moduleName: %{public}s, abilityName: %{public}s", where,
10024             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
10025         AAFwk::Want want;
10026         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
10027         if (sessionInfo.want != nullptr) {
10028             want.SetParams(sessionInfo.want->GetParams());
10029             want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int>(sessionInfo.screenId_));
10030         }
10031         auto result = AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
10032         CloseAllFd(sessionInfo.want);
10033         TLOGNI(WmsLogTag::WMS_LIFE, "start specified ability by SCB result: %{public}d", result);
10034         if (result == ERR_OK) {
10035             return;
10036         }
10037         auto task = [bundleName = sessionInfo.bundleName_, appInstanceKey = sessionInfo.appInstanceKey_] {
10038             MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCountByBundleNameAndInstanceKey(
10039                 bundleName, appInstanceKey);
10040         };
10041         taskScheduler_->PostAsyncTask(task, where);
10042     });
10043 }
10044 
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)10045 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
10046 {
10047     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
10048     if (pid == -1) {
10049         TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
10050         return;
10051     }
10052     int32_t ret = HiSysEventWrite(
10053         HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
10054         "WINDOW_STATE_ERROR",
10055         HiviewDFX::HiSysEvent::EventType::FAULT,
10056         "PID", pid,
10057         "PERSISTENT_ID", persistentId);
10058     if (ret != 0) {
10059         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
10060     }
10061     auto task = [this, pid] {
10062         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10063         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10064             if (!sceneSession || pid != sceneSession->GetCallingPid() ||
10065                 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10066                 continue;
10067             }
10068             auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
10069             TLOGNI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
10070                 abilitySessionInfo->persistentId);
10071             sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
10072         }
10073     };
10074     // delay 2000ms, wait for hidumper
10075     taskScheduler_->PostAsyncTask(task, __func__, 2000);
10076 }
10077 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)10078 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
10079 {
10080     if (!targetToken) {
10081         TLOGE(WmsLogTag::DEFAULT, "Token is null, cannot find main window");
10082         return nullptr;
10083     }
10084 
10085     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10086     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
10087         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
10088             if (pair.second->IsTerminated()) {
10089                 return false;
10090             }
10091             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10092                 return pair.second->GetAbilityToken() == targetToken;
10093             }
10094             return false;
10095         });
10096     if (iter == sceneSessionMap_.end()) {
10097         TLOGE(WmsLogTag::DEFAULT, "Cannot find session");
10098         return nullptr;
10099     }
10100     return iter->second;
10101 }
10102 
ConfigSupportCreateFloatWindow()10103 void SceneSessionManager::ConfigSupportCreateFloatWindow()
10104 {
10105     auto task = [this] {
10106         systemConfig_.supportCreateFloatWindow_ = true;
10107     };
10108     taskScheduler_->PostAsyncTask(task, "ConfigSupportCreateFloatWindow");
10109 }
10110 
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)10111 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
10112 {
10113     if (!SessionPermission::IsSystemCalling()) {
10114         TLOGE(WmsLogTag::WMS_DIALOG, "permission denied!");
10115         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10116     }
10117     if (targetToken == nullptr) {
10118         TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
10119         return WSError::WS_ERROR_NULLPTR;
10120     }
10121 
10122     auto task = [this, persistentId, targetToken]() {
10123         auto sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
10124         if (sceneSession == nullptr) {
10125             TLOGNE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
10126             return WSError::WS_ERROR_NULLPTR;
10127         }
10128         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
10129             TLOGNE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", sceneSession->GetWindowType());
10130             return WSError::WS_OK;
10131         }
10132         sceneSession->dialogTargetToken_ = targetToken;
10133         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
10134         if (parentSession == nullptr) {
10135             sceneSession->NotifyDestroy();
10136             return WSError::WS_ERROR_INVALID_PARAM;
10137         }
10138         sptr<WindowSessionProperty> parentProperty = parentSession->GetSessionProperty();
10139         sptr<WindowSessionProperty> property = sceneSession->GetSessionProperty();
10140         auto displayId = parentProperty->GetDisplayId();
10141         property->SetDisplayId(displayId);
10142         sceneSession->SetScreenId(displayId);
10143         sceneSession->SetParentSession(parentSession);
10144         sceneSession->SetParentPersistentId(parentSession->GetPersistentId());
10145         sceneSession->SetClientDisplayId(parentSession->GetClientDisplayId());
10146         UpdateParentSessionForDialog(sceneSession, sceneSession->GetSessionProperty());
10147         TLOGNI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
10148             persistentId, parentSession->GetPersistentId());
10149         return WSError::WS_OK;
10150     };
10151     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
10152 }
10153 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)10154 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
10155     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
10156 {
10157     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
10158 }
10159 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)10160 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
10161     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
10162 {
10163     auto isSaCall = SessionPermission::IsSACalling();
10164     if (!isSaCall) {
10165         TLOGE(WmsLogTag::DEFAULT, "The interface only support for sa call");
10166         return WMError::WM_ERROR_INVALID_PERMISSION;
10167     }
10168     auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
10169         std::map<int32_t, sptr<SceneSession>>::iterator iter;
10170         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10171         for (auto missionId : missionIds) {
10172             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
10173             if (iter == sceneSessionMap_.end()) {
10174                 continue;
10175             }
10176             auto sceneSession = iter->second;
10177             if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
10178                 continue;
10179             }
10180             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
10181             GetSurfaceNodeIdsFromSubSession(sceneSession, surfaceNodeIds);
10182             if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
10183                 surfaceNodeIds.push_back(missionId);
10184                 continue;
10185             }
10186             if (sceneSession->GetLeashWinSurfaceNode()) {
10187                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
10188             }
10189         }
10190         return WMError::WM_OK;
10191     };
10192     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
10193 }
10194 
GetSurfaceNodeIdsFromSubSession(const sptr<SceneSession> & sceneSession,std::vector<uint64_t> & surfaceNodeIds)10195 WMError SceneSessionManager::GetSurfaceNodeIdsFromSubSession(
10196     const sptr<SceneSession>& sceneSession, std::vector<uint64_t>& surfaceNodeIds)
10197 {
10198     if (sceneSession == nullptr) {
10199         return WMError::WM_DO_NOTHING;
10200     }
10201     for (const auto& subSession : sceneSession->GetSubSession()) {
10202         if (subSession == nullptr) {
10203             continue;
10204         }
10205         GetSurfaceNodeIdsFromSubSession(subSession, surfaceNodeIds);
10206     }
10207     if (sceneSession->GetSurfaceNode() == nullptr) {
10208         return WMError::WM_DO_NOTHING;
10209     }
10210     surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
10211     if (sceneSession->GetLeashWinSurfaceNode()) {
10212         surfaceNodeIds.push_back(static_cast<uint64_t>(sceneSession->GetPersistentId()));
10213     }
10214     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, surfaceId: %{public}" PRIu64,
10215         sceneSession->GetPersistentId(), sceneSession->GetSurfaceNode()->GetId());
10216     return WMError::WM_OK;
10217 }
10218 
OnSetSurfaceNodeIds(DisplayId displayId,const std::vector<uint64_t> & surfaceNodeIds)10219 void DisplayChangeListener::OnSetSurfaceNodeIds(DisplayId displayId, const std::vector<uint64_t>& surfaceNodeIds)
10220 {
10221     SceneSessionManager::GetInstance().SetSurfaceNodeIds(displayId, surfaceNodeIds);
10222 }
10223 
SetSurfaceNodeIds(DisplayId displayId,const std::vector<uint64_t> & surfaceNodeIds)10224 WMError SceneSessionManager::SetSurfaceNodeIds(DisplayId displayId, const std::vector<uint64_t>& surfaceNodeIds)
10225 {
10226     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId: %{public}" PRIu64, displayId);
10227     auto task = [this, displayId, &surfaceNodeIds, where = __func__]() {
10228         for (auto it = sessionBlackListInfoMap_[displayId].begin(); it != sessionBlackListInfoMap_[displayId].end(); ) {
10229             if (it->privacyWindowTag == WMS_DEFAULT) {
10230                 it = sessionBlackListInfoMap_[displayId].erase(it);
10231             } else {
10232                 ++it;
10233             }
10234         }
10235         for (auto surfaceNodeId : surfaceNodeIds) {
10236             sptr<SceneSession> sceneSession = SelectSesssionFromMap(surfaceNodeId);
10237             if (sceneSession == nullptr) {
10238                 continue;
10239             }
10240             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: %{public}d, %{public}" PRIu64,
10241                 where, sceneSession->GetPersistentId(), surfaceNodeId);
10242             sessionBlackListInfoMap_[displayId].insert({ .windowId = sceneSession->GetPersistentId() });
10243         }
10244         UpdateVirtualScreenBlackList(displayId);
10245         return WMError::WM_OK;
10246     };
10247     return taskScheduler_->PostSyncTask(task, __func__);
10248 }
10249 
OnVirtualScreenDisconnected(DisplayId displayId)10250 void DisplayChangeListener::OnVirtualScreenDisconnected(DisplayId displayId)
10251 {
10252     SceneSessionManager::GetInstance().OnVirtualScreenDisconnected(displayId);
10253 }
10254 
OnVirtualScreenDisconnected(DisplayId displayId)10255 WMError SceneSessionManager::OnVirtualScreenDisconnected(DisplayId displayId)
10256 {
10257     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId: %{public}" PRIu64, displayId);
10258     auto task = [this, displayId, where = __func__]() {
10259         bool isSessionBlackListErased = sessionBlackListInfoMap_.erase(displayId) > 0;
10260         bool isScreenConfigErased = screenRSBlackListConfigMap_.erase(displayId) > 0;
10261         if (isSessionBlackListErased || isScreenConfigErased) {
10262             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: displayId %{public}" PRIu64, where, displayId);
10263             return WMError::WM_OK;
10264         }
10265         return WMError::WM_DO_NOTHING;
10266     };
10267     return taskScheduler_->PostSyncTask(task, __func__);
10268 }
10269 
AddSessionBlackList(const std::unordered_set<std::string> & bundleNames,const std::unordered_set<std::string> & privacyWindowTags)10270 WMError SceneSessionManager::AddSessionBlackList(
10271     const std::unordered_set<std::string>& bundleNames, const std::unordered_set<std::string>& privacyWindowTags)
10272 {
10273     if (!SessionPermission::IsSACalling()) {
10274         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
10275         return WMError::WM_ERROR_INVALID_PERMISSION;
10276     }
10277     for (const auto& bundleName : bundleNames) {
10278         bundleRSBlackListConfigMap_.insert({ bundleName, {} });
10279         bundleRSBlackListConfigMap_[bundleName].insert(privacyWindowTags.begin(), privacyWindowTags.end());
10280     }
10281     std::vector<sptr<SceneSession>> sceneSessionList;
10282     {
10283         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10284         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10285             if (sceneSession && bundleNames.find(sceneSession->GetSessionInfo().bundleName_) != bundleNames.end()) {
10286                 sceneSessionList.emplace_back(sceneSession);
10287             }
10288         }
10289     }
10290     return AddSessionBlackList(sceneSessionList, privacyWindowTags);
10291 }
10292 
AddSessionBlackList(const std::vector<sptr<SceneSession>> & sceneSessionList,const std::unordered_set<std::string> & privacyWindowTags)10293 WMError SceneSessionManager::AddSessionBlackList(const std::vector<sptr<SceneSession>>& sceneSessionList,
10294     const std::unordered_set<std::string>& privacyWindowTags)
10295 {
10296     for (const auto& sceneSession : sceneSessionList) {
10297         for (const auto& privacyWindowTag : privacyWindowTags) {
10298             sessionRSBlackListConfigSet_.insert(
10299                 { .windowId = sceneSession->GetPersistentId(), .privacyWindowTag = privacyWindowTag });
10300         }
10301     }
10302     return FlushSessionBlackListInfoMapWhenAdd();
10303 }
10304 
RemoveSessionBlackList(const std::unordered_set<std::string> & bundleNames,const std::unordered_set<std::string> & privacyWindowTags)10305 WMError SceneSessionManager::RemoveSessionBlackList(
10306     const std::unordered_set<std::string>& bundleNames, const std::unordered_set<std::string>& privacyWindowTags)
10307 {
10308     if (!SessionPermission::IsSACalling()) {
10309         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
10310         return WMError::WM_ERROR_INVALID_PERMISSION;
10311     }
10312     for (const auto& bundleName : bundleNames) {
10313         bundleRSBlackListConfigMap_.insert({ bundleName, {} });
10314         for(const auto& privacyWindowTag : privacyWindowTags) {
10315             bundleRSBlackListConfigMap_[bundleName].erase(privacyWindowTag);
10316         }
10317         if (bundleRSBlackListConfigMap_[bundleName].empty()) {
10318             bundleRSBlackListConfigMap_.erase(bundleName);
10319         }
10320     }
10321     std::vector<sptr<SceneSession>> sceneSessionList;
10322     {
10323         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10324         for (const auto& [_, sceneSession] : sceneSessionMap_) {
10325             if (sceneSession && bundleNames.find(sceneSession->GetSessionInfo().bundleName_) != bundleNames.end()) {
10326                 sceneSessionList.emplace_back(sceneSession);
10327             }
10328         }
10329     }
10330     return RemoveSessionBlackList(sceneSessionList, privacyWindowTags);
10331 }
10332 
RemoveSessionBlackList(const std::vector<sptr<SceneSession>> & sceneSessionList,const std::unordered_set<std::string> & privacyWindowTags)10333 WMError SceneSessionManager::RemoveSessionBlackList(const std::vector<sptr<SceneSession>>& sceneSessionList,
10334     const std::unordered_set<std::string>& privacyWindowTags)
10335 {
10336     for (const auto& sceneSession : sceneSessionList) {
10337         for (const auto& privacyWindowTag : privacyWindowTags) {
10338             sessionRSBlackListConfigSet_.erase(
10339                 { .windowId = sceneSession->GetPersistentId(), .privacyWindowTag = privacyWindowTag });
10340         }
10341     }
10342     return FlushSessionBlackListInfoMapWhenRemove();
10343 }
10344 
FlushSessionBlackListInfoMapWhenAdd()10345 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenAdd()
10346 {
10347     for (const auto& [screenId, screenBlackListInfo] : screenRSBlackListConfigMap_) {
10348         for (const auto& info : sessionRSBlackListConfigSet_) {
10349             if (screenBlackListInfo.find({ .privacyWindowTag = info.privacyWindowTag }) != screenBlackListInfo.end()) {
10350                 sessionBlackListInfoMap_[screenId].insert(info);
10351             }
10352         }
10353         UpdateVirtualScreenBlackList(screenId);
10354     }
10355     return WMError::WM_OK;
10356 }
10357 
FlushSessionBlackListInfoMapWhenAdd(ScreenId screenId)10358 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenAdd(ScreenId screenId)
10359 {
10360     auto screenBlackListInfo = screenRSBlackListConfigMap_[screenId];
10361     for (const auto& info : sessionRSBlackListConfigSet_) {
10362         if (screenBlackListInfo.find({ .privacyWindowTag = info.privacyWindowTag }) != screenBlackListInfo.end()) {
10363             sessionBlackListInfoMap_[screenId].insert(info);
10364         }
10365     }
10366     UpdateVirtualScreenBlackList(screenId);
10367     return WMError::WM_OK;
10368 }
10369 
FlushSessionBlackListInfoMapWhenRemove()10370 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenRemove()
10371 {
10372     for (auto& [screenId, infoSet] : sessionBlackListInfoMap_) {
10373         for (auto it = infoSet.begin(); it != infoSet.end(); ) {
10374             const auto& info = *it;
10375             if (info.privacyWindowTag == WMS_DEFAULT) {
10376                 ++it;
10377                 continue;
10378             }
10379             bool notInScreenConfigMap = screenRSBlackListConfigMap_[screenId].find(
10380                 { .privacyWindowTag = info.privacyWindowTag }) == screenRSBlackListConfigMap_[screenId].end();
10381             bool notInSessionConfigSet = sessionRSBlackListConfigSet_.find(info) == sessionRSBlackListConfigSet_.end();
10382             if (notInScreenConfigMap || notInSessionConfigSet) {
10383                 it = infoSet.erase(it);
10384             } else {
10385                 ++it;
10386             }
10387         }
10388         UpdateVirtualScreenBlackList(screenId);
10389     }
10390     return WMError::WM_OK;
10391 }
10392 
FlushSessionBlackListInfoMapWhenRemove(ScreenId screenId)10393 WMError SceneSessionManager::FlushSessionBlackListInfoMapWhenRemove(ScreenId screenId)
10394 {
10395     if (sessionBlackListInfoMap_.find(screenId) == sessionBlackListInfoMap_.end()) {
10396         std::vector<uint64_t> emptyList;
10397         rsInterface_.SetVirtualScreenBlackList(screenId, emptyList);
10398         return WMError::WM_OK;
10399     }
10400     auto& infoSet = sessionBlackListInfoMap_[screenId];
10401     for (auto it = infoSet.begin(); it != infoSet.end(); ) {
10402         const auto& info = *it;
10403         if (info.privacyWindowTag == WMS_DEFAULT) {
10404             ++it;
10405             continue;
10406         }
10407         bool notInScreenConfigMap = screenRSBlackListConfigMap_[screenId].find(
10408             { .privacyWindowTag = info.privacyWindowTag }) == screenRSBlackListConfigMap_[screenId].end();
10409         bool notInSessionConfigSet = sessionRSBlackListConfigSet_.find(info) == sessionRSBlackListConfigSet_.end();
10410         if (notInScreenConfigMap || notInSessionConfigSet) {
10411             it = infoSet.erase(it);
10412         } else {
10413             ++it;
10414         }
10415     }
10416     UpdateVirtualScreenBlackList(screenId);
10417     return WMError::WM_OK;
10418 }
10419 
UpdateVirtualScreenBlackList(ScreenId screenId)10420 void SceneSessionManager::UpdateVirtualScreenBlackList(ScreenId screenId)
10421 {
10422     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "Configsize: [%{public}zu, %{public}zu], %{public}zu",
10423         sessionRSBlackListConfigSet_.size(), screenRSBlackListConfigMap_.size(), sessionBlackListInfoMap_.size());
10424     std::unordered_set<uint64_t> skipSurfaceNodeIdSet;
10425     for (const auto& info : sessionBlackListInfoMap_[screenId]) {
10426         AddskipSurfaceNodeIdSet(info.windowId, skipSurfaceNodeIdSet);
10427     }
10428     std::vector<uint64_t> skipSurfaceNodeIds(skipSurfaceNodeIdSet.begin(), skipSurfaceNodeIdSet.end());
10429     std::ostringstream oss;
10430     oss << "surfaceNodeIds[" << screenId << "]: ";
10431     for (auto id : skipSurfaceNodeIds) {
10432         oss << id << " ";
10433     }
10434     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "%{public}s", oss.str().c_str());
10435     rsInterface_.SetVirtualScreenBlackList(screenId, skipSurfaceNodeIds);
10436 }
10437 
NotifyOnAttachToFrameNode(const sptr<Session> & session)10438 void SceneSessionManager::NotifyOnAttachToFrameNode(const sptr<Session>& session)
10439 {
10440     auto where = __func__;
10441     wptr<Session> weakSession(session);
10442     auto task = [this, weakSession, where] {
10443         auto session = weakSession.promote();
10444         if (session == nullptr) {
10445             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s, session is nullptr", where);
10446             return;
10447         }
10448         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s, wid: %{public}d", where, session->GetPersistentId());
10449         if (WindowHelper::IsMainWindow(session->GetWindowType())) {
10450             AddSkipSurfaceNodeWhenAttach(session->GetPersistentId(),
10451                 session->GetSessionInfo().bundleName_, static_cast<uint64_t>(session->GetPersistentId()));
10452         } else {
10453             auto surfaceNode = session->GetSurfaceNode();
10454             if (surfaceNode == nullptr) {
10455                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s, surfaceNode is nullptr", where);
10456                 return;
10457             }
10458             AddSkipSurfaceNodeWhenAttach(session->GetPersistentId(),
10459                 session->GetSessionInfo().bundleName_, surfaceNode->GetId());
10460         }
10461     };
10462     taskScheduler_->PostAsyncTask(task, where);
10463 }
10464 
AddSkipSurfaceNodeWhenAttach(int32_t windowId,const std::string & bundleName,uint64_t surfaceNodeId)10465 void SceneSessionManager::AddSkipSurfaceNodeWhenAttach(
10466     int32_t windowId, const std::string& bundleName, uint64_t surfaceNodeId)
10467 {
10468     if (bundleRSBlackListConfigMap_.find(bundleName) != bundleRSBlackListConfigMap_.end()) {
10469         for (const auto& tag : bundleRSBlackListConfigMap_[bundleName]) {
10470             sessionRSBlackListConfigSet_.insert({ .windowId = windowId, .privacyWindowTag = tag });
10471             for (const auto& [screenId, infoSet] : screenRSBlackListConfigMap_) {
10472                 if (infoSet.find({ .privacyWindowTag = tag }) != infoSet.end()) {
10473                     sessionBlackListInfoMap_[screenId].insert({ .windowId = windowId, .privacyWindowTag = tag });
10474                     std::vector<uint64_t> skipSurfaceNodeIds = { surfaceNodeId };
10475                     rsInterface_.AddVirtualScreenBlackList(screenId, skipSurfaceNodeIds);
10476                 }
10477             }
10478         }
10479     }
10480 }
10481 
AddskipSurfaceNodeIdSet(int32_t windowId,std::unordered_set<uint64_t> & skipSurfaceNodeIdSet)10482 void SceneSessionManager::AddskipSurfaceNodeIdSet(int32_t windowId, std::unordered_set<uint64_t>& skipSurfaceNodeIdSet)
10483 {
10484     auto sceneSession = GetSceneSession(windowId);
10485     if (sceneSession == nullptr) {
10486         return;
10487     }
10488     if (SessionHelper::IsMainWindow(static_cast<WindowType>(sceneSession->GetWindowType()))) {
10489         auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
10490         if (leashWinSurfaceNode != nullptr) {
10491             skipSurfaceNodeIdSet.insert(static_cast<uint64_t>(sceneSession->GetPersistentId()));
10492         }
10493     }
10494     auto surfaceNode = sceneSession->GetSurfaceNode();
10495     if (surfaceNode != nullptr) {
10496         skipSurfaceNodeIdSet.insert(surfaceNode->GetId());
10497     }
10498 }
10499 
UpdateSubSessionBlackList(const sptr<SceneSession> & sceneSession)10500 WMError SceneSessionManager::UpdateSubSessionBlackList(const sptr<SceneSession>& sceneSession)
10501 {
10502     WMError ret = WMError::WM_DO_NOTHING;
10503     auto parentSession = sceneSession->GetParentSession();
10504     if (parentSession == nullptr) {
10505         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "win: %{public}d parent session is null", sceneSession->GetPersistentId());
10506         return ret;
10507     }
10508     SessionBlackListInfo parentSessionBlackListInfo = { .windowId = parentSession->GetPersistentId() };
10509     ScreenId rsScreenId = SCREEN_ID_INVALID;
10510     for (auto& [displayId, sessionBlackListInfoSet] : sessionBlackListInfoMap_) {
10511         if (sessionBlackListInfoSet.count(parentSessionBlackListInfo) > 0) {
10512             sessionBlackListInfoSet.insert({ .windowId = sceneSession->GetPersistentId() });
10513             rsScreenId = displayId;
10514             ret = WMError::WM_OK;
10515         }
10516     }
10517     if (ret != WMError::WM_OK) {
10518         return ret;
10519     }
10520     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "rsScreenId: %{public}" PRIu64 " win: %{public}d parentId: %{public}d",
10521         rsScreenId, sceneSession->GetPersistentId(), parentSession->GetPersistentId());
10522     SessionBlackListInfoSet funcSet = sessionBlackListInfoMap_[rsScreenId];
10523     std::vector<uint64_t> surfaceNodeIds;
10524     for (const auto& sessionBlackListInfo : funcSet) {
10525         sptr<SceneSession> session = GetSceneSession(sessionBlackListInfo.windowId);
10526         if (session == nullptr) {
10527             TLOGW(WmsLogTag::WMS_ATTRIBUTE, "session %{public}d is null", sessionBlackListInfo.windowId);
10528             continue;
10529         }
10530         if (session->GetSurfaceNode() == nullptr) {
10531             TLOGW(WmsLogTag::WMS_ATTRIBUTE, "surfaceNode %{public}d is null", sessionBlackListInfo.windowId);
10532             continue;
10533         }
10534         surfaceNodeIds.push_back(session->GetSurfaceNode()->GetId());
10535         if (session->GetLeashWinSurfaceNode()) {
10536             surfaceNodeIds.push_back(static_cast<uint64_t>(session->GetPersistentId()));
10537         }
10538     }
10539     std::ostringstream oss;
10540     oss << "surfaceNodeIds[" << rsScreenId << "]: ";
10541     for (auto id : surfaceNodeIds) {
10542         oss << id << " ";
10543     }
10544     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s", oss.str().c_str());
10545     rsInterface_.SetVirtualScreenBlackList(rsScreenId, surfaceNodeIds);
10546     return ret;
10547 }
10548 
RemoveSessionFromBlackList(const sptr<SceneSession> & sceneSession)10549 WMError SceneSessionManager::RemoveSessionFromBlackList(const sptr<SceneSession>& sceneSession)
10550 {
10551     WMError ret = WMError::WM_DO_NOTHING;
10552     if (sceneSession == nullptr) {
10553         return ret;
10554     }
10555     RemoveSessionFromBlackListInfoSet(sceneSession, sessionRSBlackListConfigSet_);
10556     for (auto it = sessionBlackListInfoMap_.begin(); it != sessionBlackListInfoMap_.end();) {
10557         auto& sessionBlackListInfoSet = it->second;
10558         RemoveSessionFromBlackListInfoSet(sceneSession, sessionBlackListInfoSet);
10559         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
10560             sceneSession->GetPersistentId(), it->first);
10561         ret = WMError::WM_OK;
10562         if (sessionBlackListInfoSet.empty()) {
10563             it = sessionBlackListInfoMap_.erase(it);
10564         } else {
10565             ++it;
10566         }
10567     }
10568     return ret;
10569 }
10570 
RemoveSessionFromBlackListInfoSet(const sptr<SceneSession> & sceneSession,SessionBlackListInfoSet & sessionBlackListInfoSet)10571 void SceneSessionManager::RemoveSessionFromBlackListInfoSet(
10572     const sptr<SceneSession>& sceneSession, SessionBlackListInfoSet& sessionBlackListInfoSet)
10573 {
10574     for (auto it = sessionBlackListInfoSet.begin(); it != sessionBlackListInfoSet.end();) {
10575         if (it->windowId == sceneSession->GetPersistentId()) {
10576             it = sessionBlackListInfoSet.erase(it);
10577         } else {
10578             ++it;
10579         }
10580     }
10581 }
10582 
RecoverWindowPropertyChangeFlag(uint32_t observedFlags,uint32_t interestedFlags)10583 WMError SceneSessionManager::RecoverWindowPropertyChangeFlag(uint32_t observedFlags, uint32_t interestedFlags)
10584 {
10585     observedFlags_ |= observedFlags;
10586     interestedFlags_ |= interestedFlags;
10587     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "observedFlags: %{public}u, interestedFlags: %{public}u",
10588         observedFlags_, interestedFlags_);
10589     return WMError::WM_OK;
10590 }
10591 
RegisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,uint32_t interestInfo,const sptr<IWindowManagerAgent> & windowManagerAgent)10592 WMError SceneSessionManager::RegisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,
10593     uint32_t interestInfo, const sptr<IWindowManagerAgent>& windowManagerAgent)
10594 {
10595     observedFlags_ |= static_cast<uint32_t>(windowInfoKey);
10596     interestedFlags_ |= interestInfo;
10597     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "observedFlags: %{public}u, interestedFlags: %{public}u",
10598         observedFlags_, interestedFlags_);
10599     return RegisterWindowManagerAgent(
10600         WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY, windowManagerAgent);
10601 }
10602 
UnregisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,uint32_t interestInfo,const sptr<IWindowManagerAgent> & windowManagerAgent)10603 WMError SceneSessionManager::UnregisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey,
10604     uint32_t interestInfo, const sptr<IWindowManagerAgent>& windowManagerAgent)
10605 {
10606     observedFlags_ &= ~(static_cast<uint32_t>(windowInfoKey));
10607     interestedFlags_ &= ~interestInfo;
10608     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "observedFlags: %{public}u, interestedFlags: %{public}u",
10609         observedFlags_, interestedFlags_);
10610     return UnregisterWindowManagerAgent(
10611         WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY, windowManagerAgent);
10612 }
10613 
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)10614 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
10615     const sptr<IWindowManagerAgent>& windowManagerAgent)
10616 {
10617     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
10618         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
10619         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
10620         if (!SessionPermission::IsSystemCalling()) {
10621             TLOGE(WmsLogTag::DEFAULT, "permission denied!");
10622             return WMError::WM_ERROR_NOT_SYSTEM_APP;
10623         }
10624     } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
10625         if (!SessionPermission::IsSystemServiceCalling()) {
10626             return WMError::WM_ERROR_INVALID_PERMISSION;
10627         }
10628     }
10629     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
10630         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
10631         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
10632         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
10633         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
10634         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY ||
10635         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY) {
10636         if (!SessionPermission::IsSACalling()) {
10637             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10638             return WMError::WM_ERROR_INVALID_PERMISSION;
10639         }
10640     }
10641     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
10642         TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
10643         return WMError::WM_ERROR_NULLPTR;
10644     }
10645     const auto callingPid = IPCSkeleton::GetCallingRealPid();
10646     auto task = [this, windowManagerAgent, type, callingPid]() {
10647         return SessionManagerAgentController::GetInstance()
10648             .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
10649     };
10650     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
10651 }
10652 
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)10653 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
10654     const sptr<IWindowManagerAgent>& windowManagerAgent)
10655 {
10656     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
10657         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
10658         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
10659         if (!SessionPermission::IsSystemCalling()) {
10660             TLOGE(WmsLogTag::DEFAULT, "IsSystemCalling permission denied!");
10661             return WMError::WM_ERROR_NOT_SYSTEM_APP;
10662         }
10663     }
10664     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
10665         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
10666         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
10667         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
10668         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
10669         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_PROPERTY) {
10670         if (!SessionPermission::IsSACalling()) {
10671             TLOGE(WmsLogTag::WMS_LIFE, "IsSACalling permission denied!");
10672             return WMError::WM_ERROR_INVALID_PERMISSION;
10673         }
10674     }
10675     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
10676         TLOGE(WmsLogTag::DEFAULT, "windowManagerAgent is null");
10677         return WMError::WM_ERROR_NULLPTR;
10678     }
10679     const auto callingPid = IPCSkeleton::GetCallingRealPid();
10680     auto task = [this, windowManagerAgent, type, callingPid]() {
10681         return SessionManagerAgentController::GetInstance()
10682             .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
10683     };
10684     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
10685 }
10686 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)10687 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
10688 {
10689     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
10690 }
10691 
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)10692 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
10693 {
10694     SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
10695 }
10696 
StartWindowInfoReportLoop()10697 void SceneSessionManager::StartWindowInfoReportLoop()
10698 {
10699     TLOGD(WmsLogTag::WMS_STARTUP_PAGE, "in");
10700     if (isReportTaskStart_) {
10701         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "Report is ReportTask Start");
10702         return;
10703     }
10704     auto task = [this] {
10705         WindowInfoReporter::GetInstance().ReportRecordedInfos();
10706         ReportWindowProfileInfos();
10707         isReportTaskStart_ = false;
10708         StartWindowInfoReportLoop();
10709     };
10710     int64_t delayTime = 1000 * 60 * 60; // an hour.
10711     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
10712     if (!ret) {
10713         TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "failed. task is WindowInfoReport");
10714         return;
10715     }
10716     isReportTaskStart_ = true;
10717 }
10718 
InitPersistentStorage()10719 void SceneSessionManager::InitPersistentStorage()
10720 {
10721     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
10722         int32_t storageMode = -1;
10723         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
10724         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
10725             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
10726             TLOGI(WmsLogTag::DEFAULT, "init MaximizeMode as %{public}d from persistent storage", storageMode);
10727             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
10728         }
10729     }
10730 }
10731 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)10732 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
10733 {
10734     TLOGD(WmsLogTag::DEFAULT, "in.");
10735     if (!SessionPermission::IsSystemServiceCalling()) {
10736         TLOGE(WmsLogTag::DEFAULT, "Only support for system service.");
10737         return WMError::WM_ERROR_NOT_SYSTEM_APP;
10738     }
10739     auto task = [this, &infos]() {
10740         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetAccessibilityWindowInfo");
10741         std::map<int32_t, sptr<SceneSession>>::iterator iter;
10742         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10743         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
10744             sptr<SceneSession> sceneSession = iter->second;
10745             if (sceneSession == nullptr) {
10746                 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "null scene session");
10747                 continue;
10748             }
10749             bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
10750                 sceneSession->IsVisibleForAccessibility() :
10751                 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
10752             TLOGND(WmsLogTag::WMS_ATTRIBUTE, "name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, "
10753                 "winType=%{public}d, state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
10754                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
10755                 sceneSession->GetSessionState(), isVisibleForAccessibility);
10756             if (isVisibleForAccessibility) {
10757                 FillWindowInfo(infos, iter->second);
10758             }
10759         }
10760         return WMError::WM_OK;
10761     };
10762     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
10763 }
10764 
CheckUnreliableWindowType(WindowType windowType)10765 static bool CheckUnreliableWindowType(WindowType windowType)
10766 {
10767     if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
10768         windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
10769         windowType == WindowType::WINDOW_TYPE_TOAST) {
10770         return true;
10771     }
10772     TLOGD(WmsLogTag::DEFAULT, "false, WindowType=%{public}d", windowType);
10773     return false;
10774 }
10775 
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)10776 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
10777     std::vector<sptr<UnreliableWindowInfo>>& infos)
10778 {
10779     if (sceneSession == nullptr) {
10780         TLOGW(WmsLogTag::DEFAULT, "null scene session.");
10781         return;
10782     }
10783     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10784         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10785         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10786         TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
10787         return;
10788     }
10789     sptr<UnreliableWindowInfo> info = sptr<UnreliableWindowInfo>::MakeSptr();
10790     info->windowId_ = sceneSession->GetPersistentId();
10791     WSRect windowRect = sceneSession->GetSessionRect();
10792     info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
10793     info->zOrder_ = sceneSession->GetZOrder();
10794     info->floatingScale_ = sceneSession->GetFloatingScale();
10795     info->scaleX_ = sceneSession->GetScaleX();
10796     info->scaleY_ = sceneSession->GetScaleY();
10797     infos.emplace_back(info);
10798     TLOGD(WmsLogTag::WMS_MAIN, "wid=%{public}d", info->windowId_);
10799 }
10800 
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)10801 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
10802     std::vector<sptr<UnreliableWindowInfo>>& infos)
10803 {
10804     TLOGD(WmsLogTag::DEFAULT, "in.");
10805     if (!SessionPermission::IsSystemServiceCalling()) {
10806         TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
10807         return WMError::WM_ERROR_NOT_SYSTEM_APP;
10808     }
10809     auto task = [this, windowId, &infos]() {
10810         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10811         for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
10812             if (sceneSession == nullptr) {
10813                 TLOGNW(WmsLogTag::DEFAULT, "null scene session");
10814                 continue;
10815             }
10816             if (sessionId == windowId) {
10817                 TLOGNI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
10818                 FillUnreliableWindowInfo(sceneSession, infos);
10819                 continue;
10820             }
10821             if (sceneSession->GetSystemTouchable() && sceneSession->GetForegroundInteractiveStatus()) {
10822                 TLOGND(WmsLogTag::DEFAULT, "persistentId: %{public}d is system touchable", sessionId);
10823                 continue;
10824             }
10825             if (!sceneSession->GetRSVisible()) {
10826                 TLOGND(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
10827                 continue;
10828             }
10829             TLOGND(WmsLogTag::DEFAULT, "name=%{public}s, isSystem=%{public}d, "
10830                 "persistentId=%{public}d, winType=%{public}d, state=%{public}d, visible=%{public}d",
10831                 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
10832                 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
10833             if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
10834                 TLOGI(WmsLogTag::DEFAULT, "persistentId=%{public}d, "
10835                     "WindowType=%{public}d", sessionId, sceneSession->GetWindowType());
10836                 FillUnreliableWindowInfo(sceneSession, infos);
10837             }
10838         }
10839         return WMError::WM_OK;
10840     };
10841     return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
10842 }
10843 
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)10844 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
10845 {
10846     TLOGD(WmsLogTag::DEFAULT, "persistentId=%{public}d, updateType=%{public}d", persistentId, type);
10847     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
10848     if (sceneSession == nullptr) {
10849         TLOGD(WmsLogTag::DEFAULT, "sceneSession nullptr!");
10850         return;
10851     }
10852     wptr<SceneSession> weakSceneSession(sceneSession);
10853     if (processingFlushUIParams_.load()) {
10854         TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
10855         auto task = [this, weakSceneSession, type]() {
10856             auto sceneSession = weakSceneSession.promote();
10857             if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
10858                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10859                 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
10860             }
10861         };
10862         taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
10863         return;
10864     }
10865     auto task = [this, weakSceneSession, type]() {
10866         auto sceneSession = weakSceneSession.promote();
10867         NotifyAllAccessibilityInfo();
10868         if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
10869             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10870             WindowChangedFunc_(sceneSession->GetPersistentId(), type);
10871         }
10872     };
10873     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
10874     auto notifySceneInputTask = [weakSceneSession, type]() {
10875         auto sceneSession = weakSceneSession.promote();
10876         if (sceneSession == nullptr) {
10877             return;
10878         }
10879         SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
10880     };
10881     taskScheduler_->PostAsyncTask(notifySceneInputTask, "notifySceneInputTask");
10882 }
10883 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)10884 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
10885     const sptr<SceneSession>& sceneSession)
10886 {
10887     if (sceneSession == nullptr) {
10888         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "null scene session.");
10889         return false;
10890     }
10891     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10892         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10893         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10894         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter gesture window.");
10895         return false;
10896     }
10897     if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
10898         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "filter DragScale window.");
10899         return false;
10900     }
10901     if (sceneSession->GetHidingStartingWindow()) {
10902         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "filter hiding starting win: %{public}d", sceneSession->GetPersistentId());
10903         return false;
10904     }
10905     sptr<AccessibilityWindowInfo> info = sptr<AccessibilityWindowInfo>::MakeSptr();
10906     if (sceneSession->GetSessionInfo().isSystem_) {
10907         info->wid_ = 1;
10908         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
10909     } else {
10910         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
10911     }
10912     info->uiNodeId_ = sceneSession->GetUINodeId();
10913     info->type_ = sceneSession->GetWindowType();
10914     info->mode_ = sceneSession->GetWindowMode();
10915     info->layer_ = sceneSession->GetZOrder();
10916     info->scaleVal_ = sceneSession->GetFloatingScale();
10917     info->scaleX_ = sceneSession->GetScaleX();
10918     info->scaleY_ = sceneSession->GetScaleY();
10919     info->isCompatScaleMode_ = sceneSession->IsInCompatScaleMode();
10920     info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
10921     info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
10922     info->isDecorEnable_ = sceneSession->GetSessionProperty()->IsDecorEnable();
10923     WSRect wsRect = sceneSession->GetSessionGlobalRectWithSingleHandScale(); // only accessability and mmi need global
10924     DisplayId displayId = sceneSession->GetSessionProperty()->GetDisplayId();
10925     if (!sceneSession->GetSessionInfo().isSystem_ &&
10926         PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(displayId) &&
10927         !sceneSession->GetSessionProperty()->IsSystemKeyboard()) {
10928         displayId = sceneSession->TransformGlobalRectToRelativeRect(wsRect);
10929     }
10930     info->displayId_ = displayId;
10931     info->focused_ = sceneSession->GetPersistentId() == GetFocusedSessionId(displayId);
10932     info->windowRect_ = { wsRect.posX_, wsRect.posY_, wsRect.width_, wsRect.height_ };
10933     infos.emplace_back(info);
10934     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, innerWid: %{public}d, nodeId: %{public}d"
10935         ", bundleName: %{public}s, displayId: %{public}" PRIu64 ", rect: %{public}s",
10936         info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str(),
10937         info->displayId_, info->windowRect_.ToString().c_str());
10938     return true;
10939 }
10940 
SelectSesssionFromMap(const uint64_t & surfaceId)10941 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
10942 {
10943     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10944     for (const auto& [_, sceneSession] : sceneSessionMap_) {
10945         if (sceneSession == nullptr) {
10946             continue;
10947         }
10948         if (sceneSession->GetSurfaceNode() == nullptr) {
10949             continue;
10950         }
10951         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
10952             return sceneSession;
10953         }
10954     }
10955     return nullptr;
10956 }
10957 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)10958 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
10959 {
10960     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "in");
10961     auto task = [this, weak = std::weak_ptr<RSOcclusionData>(occlusiontionData)]() {
10962         auto weakOcclusionData = weak.lock();
10963         if (weakOcclusionData == nullptr) {
10964             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "weak occlusionData is nullptr");
10965             return;
10966         }
10967         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
10968         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
10969         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
10970         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
10971         if (currVisibleData.size() != 0) {
10972             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
10973         }
10974         if (visibilityChangeInfos.size() != 0) {
10975             DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
10976             CacVisibleWindowNum();
10977         }
10978 
10979         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
10980         if (currDrawingContentData.size() != 0) {
10981             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
10982         }
10983         if (drawingContentChangeInfos.size() != 0) {
10984             DealwithDrawingContentChange(drawingContentChangeInfos);
10985         }
10986     };
10987     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
10988 }
10989 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)10990 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
10991     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
10992     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
10993 {
10994     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
10995     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
10996         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
10997         auto visibilityState = static_cast<WindowVisibilityState>(iter->second);
10998         sptr<SceneSession> session = SelectSesssionFromMap(iter->first);
10999         switch (windowLayerState) {
11000             case WINDOW_ALL_VISIBLE:
11001             case WINDOW_SEMI_VISIBLE:
11002                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
11003                 break;
11004             case WINDOW_IN_VISIBLE:
11005                 if (session != nullptr && session->GetHidingStartingWindow()) {
11006                     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "change to visible: %{public}d", session->GetPersistentId());
11007                     visibilityState = WINDOW_VISIBILITY_STATE_NO_OCCLUSION;
11008                 }
11009                 currVisibleData.emplace_back(iter->first, visibilityState);
11010                 break;
11011             case WINDOW_LAYER_DRAWING:
11012                 currDrawingContentData.emplace_back(iter->first, true);
11013                 break;
11014             case WINDOW_LAYER_NO_DRAWING:
11015                 currDrawingContentData.emplace_back(iter->first, false);
11016                 break;
11017             default:
11018                 break;
11019         }
11020     }
11021 }
11022 
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)11023 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
11024     WindowVisibilityState visibleState,
11025     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
11026     std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
11027     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11028 {
11029     if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
11030             visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11031         auto subSessions = GetSubSceneSession(session->GetWindowId());
11032         if (subSessions.empty()) {
11033             return;
11034         }
11035 
11036         RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
11037 
11038         for (const auto& subSession : subSessions) {
11039             if (subSession == nullptr) {
11040                 continue;
11041             }
11042             if (GetSessionRSVisible(subSession, currVisibleData)) {
11043                 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Update subwindow visibility for winId: %{public}d",
11044                     subSession->GetWindowId());
11045                 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
11046             }
11047         }
11048     }
11049 }
11050 
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)11051 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
11052     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11053 {
11054     bool sessionRSVisible = false;
11055     for (const auto& [surfaceId, visibleState] : currVisibleData) {
11056         sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
11057         if (visibilitySession == nullptr) {
11058             continue;
11059         }
11060         if (session->GetWindowId() == visibilitySession->GetWindowId()) {
11061             if (visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11062                 sessionRSVisible = true;
11063             }
11064             break;
11065         }
11066     }
11067     return sessionRSVisible;
11068 }
11069 
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)11070 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
11071     WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
11072     std::string& visibilityInfo)
11073 {
11074     if (session == nullptr) {
11075         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Session is invalid!");
11076         return;
11077     }
11078     session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11079     session->SetVisibilityState(visibleState);
11080     int32_t windowId = session->GetWindowId();
11081     if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
11082         session->NotifyWindowVisibility();
11083     }
11084     auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(
11085         windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType());
11086     windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
11087     windowVisibilityInfo->SetBundleName(session->GetSessionInfo().bundleName_);
11088     windowVisibilityInfo->SetAbilityName(session->GetSessionInfo().abilityName_);
11089     windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
11090     windowVisibilityInfo->SetZOrder(session->GetZOrder());
11091 
11092     int32_t callingWindowId = session->GetSessionInfo().callerPersistentId_;
11093     sptr<SceneSession> callerSession = GetSceneSession(callingWindowId);
11094     if (callerSession) {
11095         windowVisibilityInfo->SetCallingPid(callerSession->GetCallingPid());
11096     }
11097     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "callingWindowId %{public}d, callingPid %{public}d",
11098         callingWindowId, windowVisibilityInfo->GetCallingPid());
11099 
11100     windowVisibilityInfos.emplace_back(windowVisibilityInfo);
11101 
11102     visibilityInfo +=
11103         "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
11104 }
11105 
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)11106 void SceneSessionManager::RemoveDuplicateSubSession(
11107     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
11108     std::vector<sptr<SceneSession>>& subSessions)
11109 {
11110     for (const auto& elem : visibilityChangeInfo) {
11111         uint64_t surfaceId = elem.first;
11112         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11113         if (session == nullptr) {
11114             continue;
11115         }
11116         for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
11117             auto subSession = *iterator;
11118             if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
11119                 iterator = subSessions.erase(iterator);
11120             } else {
11121                 ++iterator;
11122             }
11123         }
11124     }
11125 }
11126 
GetSubSceneSession(int32_t parentWindowId)11127 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
11128 {
11129     std::vector<sptr<SceneSession>> subSessions;
11130     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11131     for (const auto& iter : sceneSessionMap_) {
11132         auto sceneSession = iter.second;
11133         if (sceneSession == nullptr) {
11134             continue;
11135         }
11136         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11137             continue;
11138         }
11139         const auto& mainOrFloatSession = sceneSession->GetMainOrFloatSession();
11140         if (mainOrFloatSession != nullptr && mainOrFloatSession->GetWindowId() == parentWindowId) {
11141             subSessions.push_back(sceneSession);
11142         }
11143     }
11144     return subSessions;
11145 }
11146 
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)11147 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
11148     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11149 {
11150     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
11151     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
11152     uint32_t i, j;
11153     i = j = 0;
11154     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
11155         if (lastVisibleData_[i].first < currVisibleData[j].first) {
11156             if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
11157                 i++;
11158                 continue;
11159             }
11160             if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11161                 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11162             }
11163             i++;
11164         } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
11165             if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11166                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
11167             }
11168             j++;
11169         } else {
11170             if (lastVisibleData_[i].second != currVisibleData[j].second &&
11171                 !IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
11172                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
11173             }
11174             i++;
11175             j++;
11176         }
11177     }
11178     for (; i < lastVisibleData_.size(); ++i) {
11179         if (IsLastPiPWindowVisible(lastVisibleData_[i].first, lastVisibleData_[i].second)) {
11180             continue;
11181         }
11182         if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11183             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11184         }
11185     }
11186     for (; j < currVisibleData.size(); ++j) {
11187         if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
11188             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
11189         }
11190     }
11191     lastVisibleData_ = currVisibleData;
11192     return visibilityChangeInfo;
11193 }
11194 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)11195 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
11196     visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
11197 {
11198     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
11199 #ifdef MEMMGR_WINDOW_ENABLE
11200     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
11201 #endif
11202 
11203     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
11204     for (const auto& elem : visibilityChangeInfo) {
11205         uint64_t surfaceId = elem.first;
11206         WindowVisibilityState visibleState = elem.second;
11207         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
11208         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11209         if (session == nullptr) {
11210             continue;
11211         }
11212         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
11213             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
11214             if (session->GetParentSession() != nullptr &&
11215                 !session->GetParentSession()->IsSessionForeground() &&
11216                 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
11217                 continue;
11218             }
11219         }
11220         SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
11221         UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
11222 #ifdef MEMMGR_WINDOW_ENABLE
11223         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
11224             session->GetCallingUid(), isVisible));
11225 #endif
11226         CheckAndNotifyWaterMarkChangedResult();
11227     }
11228     if (windowVisibilityInfos.size() != 0) {
11229         TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
11230             visibilityInfo.c_str());
11231         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
11232     }
11233     ProcessWindowModeType();
11234 #ifdef MEMMGR_WINDOW_ENABLE
11235     if (memMgrWindowInfos.size() != 0) {
11236         TLOGND(WmsLogTag::WMS_ATTRIBUTE, "Notify memMgrWindowInfos changed start");
11237         taskScheduler_ ->AddExportTask("notifyMemMgr", [memMgrWindowInfos = std::move(memMgrWindowInfos)]() {
11238             Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
11239         });
11240     }
11241 #endif
11242 }
11243 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)11244 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
11245     drawingContentChangeInfo)
11246 {
11247     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
11248     for (const auto& [surfaceId, drawingState] : drawingContentChangeInfo) {
11249         int32_t windowId = 0;
11250         int32_t pid = 0;
11251         int32_t uid = 0;
11252         WindowType type = WindowType::APP_WINDOW_BASE;
11253         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11254         if (session == nullptr) {
11255             if (!GetSpecifiedDrawingData(surfaceId, pid, uid)) {
11256                 continue;
11257             }
11258             RemoveSpecifiedDrawingData(surfaceId);
11259         } else {
11260             windowId = session->GetWindowId();
11261             pid = session->GetCallingPid();
11262             uid = session->GetCallingUid();
11263             type = session->GetWindowType();
11264         }
11265         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(windowId, pid, uid, drawingState, type));
11266         if (openDebugTrace_) {
11267             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
11268                 "drawingState:(%d )", pid, surfaceId, drawingState);
11269         }
11270         TLOGD(WmsLogTag::DEFAULT, "drawing status changed pid:%{public}d, "
11271             "surfaceId:%{public}" PRIu64 ", drawingState:%{public}d", pid, surfaceId, drawingState);
11272     }
11273     if (windowDrawingContenInfos.size() != 0) {
11274         TLOGD(WmsLogTag::DEFAULT, "Notify WindowDrawingContenInfo changed start");
11275         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
11276     }
11277 }
11278 
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)11279 WSError SceneSessionManager::NotifyAppUseControlList(
11280     ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
11281 {
11282     TLOGI(WmsLogTag::WMS_LIFE,
11283         "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
11284         static_cast<int>(type), userId, controlList.size());
11285     if (!SessionPermission::IsSACalling()) {
11286         TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
11287         return WSError::WS_ERROR_INVALID_PERMISSION;
11288     }
11289     if (type == ControlAppType::APP_LOCK &&
11290         !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
11291         TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
11292         return WSError::WS_ERROR_INVALID_PERMISSION;
11293     }
11294     if (currentUserId_ != userId) {
11295         if (currentUserId_ != DEFAULT_USERID) {
11296             TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
11297                 currentUserId_.load(), userId);
11298             return WSError::WS_ERROR_INVALID_OPERATION;
11299         }
11300         int32_t userIdByUid = GetUserIdByUid(getuid());
11301         if (userId != userIdByUid) {
11302             TLOGW(WmsLogTag::WMS_LIFE,
11303                 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
11304                 currentUserId_.load(), userId, userIdByUid);
11305             return WSError::WS_ERROR_INVALID_OPERATION;
11306         }
11307     }
11308     taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
11309         if (notifyAppUseControlListFunc_ != nullptr) {
11310             notifyAppUseControlListFunc_(type, userId, controlList);
11311         }
11312 
11313         std::vector<sptr<SceneSession>> mainSessions;
11314         for (const auto& appUseControlInfo : controlList) {
11315             RefreshAllAppUseControlMap(appUseControlInfo, type);
11316             GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
11317             if (mainSessions.empty()) {
11318                 continue;
11319             }
11320             ControlInfo controlInfo = {
11321                 .isNeedControl = appUseControlInfo.isNeedControl_,
11322                 .isControlRecentOnly = appUseControlInfo.isControlRecentOnly_
11323             };
11324             for (const auto& session : mainSessions) {
11325                 session->NotifyUpdateAppUseControl(type, controlInfo);
11326             }
11327             mainSessions.clear();
11328         }
11329     }, __func__);
11330     return WSError::WS_OK;
11331 }
11332 
RefreshAllAppUseControlMap(const AppUseControlInfo & appUseControlInfo,ControlAppType type)11333 void SceneSessionManager::RefreshAllAppUseControlMap(const AppUseControlInfo& appUseControlInfo, ControlAppType type)
11334 {
11335     ControlInfo controlInfo = {
11336         .isNeedControl = appUseControlInfo.isNeedControl_,
11337         .isControlRecentOnly = appUseControlInfo.isControlRecentOnly_
11338     };
11339     std::string key = SessionUtils::GetAppLockKey(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_);
11340     if (!controlInfo.isNeedControl && !controlInfo.isControlRecentOnly) {
11341         if (allAppUseControlMap_.find(key) != allAppUseControlMap_.end()) {
11342             allAppUseControlMap_[key].erase(type);
11343             if (allAppUseControlMap_[key].empty()){
11344                 allAppUseControlMap_.erase(key);
11345             }
11346         }
11347     } else {
11348         allAppUseControlMap_[key][type] = controlInfo;
11349     }
11350 }
11351 
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)11352 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
11353 {
11354     taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
11355         notifyAppUseControlListFunc_ = std::move(callback);
11356     }, __func__);
11357 }
11358 
GetSpecifiedDrawingData(uint64_t surfaceId,int32_t & pid,int32_t & uid)11359 bool SceneSessionManager::GetSpecifiedDrawingData(uint64_t surfaceId, int32_t& pid, int32_t& uid)
11360 {
11361     auto it = lastDrawingSessionInfoMap_.find(surfaceId);
11362     if (it != lastDrawingSessionInfoMap_.end()) {
11363         pid = it->second.pid_;
11364         uid = it->second.uid_;
11365         return true;
11366     }
11367     return false;
11368 }
11369 
RemoveSpecifiedDrawingData(uint64_t surfaceId)11370 void SceneSessionManager::RemoveSpecifiedDrawingData(uint64_t surfaceId)
11371 {
11372     auto it = lastDrawingSessionInfoMap_.find(surfaceId);
11373     if (it != lastDrawingSessionInfoMap_.end()) {
11374         lastDrawingSessionInfoMap_.erase(it);
11375     }
11376 }
11377 
GetWindowDrawingContentChangeInfo(const std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)11378 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
11379     const std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
11380 {
11381     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
11382     for (const auto& [surfaceId, isWindowDrawing] : currDrawingContentData) {
11383         int32_t pid = 0;
11384         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11385         bool isDrawingStateChanged =
11386             session == nullptr || (GetPreWindowDrawingState(surfaceId, isWindowDrawing, pid) != isWindowDrawing &&
11387                                    GetProcessDrawingState(surfaceId, pid));
11388         if (isDrawingStateChanged) {
11389             processDrawingContentChangeInfo.emplace_back(surfaceId, isWindowDrawing);
11390         }
11391     }
11392     return processDrawingContentChangeInfo;
11393 }
11394 
GetPreWindowDrawingState(uint64_t surfaceId,bool currentWindowDrawing,int32_t & pid)11395 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t surfaceId, bool currentWindowDrawing, int32_t& pid)
11396 {
11397     sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
11398     if (session == nullptr) {
11399         return false;
11400     }
11401     pid = session->GetCallingPid();
11402     bool preWindowDrawing = session->GetDrawingContentState();
11403     session->SetDrawingContentState(currentWindowDrawing);
11404     UpdateWindowDrawingData(surfaceId, pid, session->GetCallingUid());
11405     return preWindowDrawing;
11406 }
11407 
UpdateWindowDrawingData(uint64_t surfaceId,int32_t pid,int32_t uid)11408 void SceneSessionManager::UpdateWindowDrawingData(uint64_t surfaceId, int32_t pid, int32_t uid)
11409 {
11410     lastDrawingSessionInfoMap_[surfaceId] = { pid, uid };
11411 }
11412 
GetProcessDrawingState(uint64_t surfaceId,int32_t pid)11413 bool SceneSessionManager::GetProcessDrawingState(uint64_t surfaceId, int32_t pid)
11414 {
11415     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11416     for (const auto& [_, sceneSession] : sceneSessionMap_) {
11417         if (sceneSession == nullptr) {
11418             continue;
11419         }
11420         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
11421             surfaceId != sceneSession->GetSurfaceNode()->GetId()) {
11422             if (sceneSession->GetDrawingContentState()) {
11423                 return false;
11424             }
11425         }
11426     }
11427     return true;
11428 }
11429 
InitWithRenderServiceAdded()11430 void SceneSessionManager::InitWithRenderServiceAdded()
11431 {
11432     auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
11433         this->WindowLayerInfoChangeCallback(occlusiontionData);
11434     };
11435     TLOGI(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback");
11436     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
11437         TLOGE(WmsLogTag::DEFAULT, "RegisterWindowVisibilityChangeCallback failed");
11438     }
11439 }
11440 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType,bool isRegularAnimation)11441 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType, bool isRegularAnimation)
11442 {
11443     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
11444         TLOGE(WmsLogTag::DEFAULT, "The input scene type is valid, scene type is %{public}d", sceneType);
11445         return WMError::WM_ERROR_INVALID_PARAM;
11446     }
11447 
11448     auto task = [this, sceneType, isRegularAnimation]() {
11449         TLOGND(WmsLogTag::WMS_PC, "Set system animated scene %{public}d.", sceneType);
11450         bool ret = rsInterface_.SetSystemAnimatedScenes(
11451             static_cast<SystemAnimatedScenes>(sceneType), isRegularAnimation);
11452         if (!ret) {
11453             TLOGNE(WmsLogTag::WMS_PC, "Set system animated scene failed.");
11454         }
11455     };
11456     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
11457     return WMError::WM_OK;
11458 }
11459 
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)11460 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
11461 {
11462     if (!SessionPermission::IsSystemCalling()) {
11463         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
11464         return WSError::WS_ERROR_NOT_SYSTEM_APP;
11465     }
11466     if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
11467         TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
11468         return WSError::WS_ERROR_INVALID_PERMISSION;
11469     }
11470     TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
11471         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
11472     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
11473     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
11474         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
11475         WindowType::WINDOW_TYPE_APP_COMPONENT));
11476     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
11477     return WSError::WS_OK;
11478 }
11479 
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)11480 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
11481 {
11482     if (sceneSession == nullptr) {
11483         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr!");
11484         return;
11485     }
11486     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "in, wid: %{public}d, RSVisible: %{public}d, WindowMode: %{public}u",
11487         sceneSession->GetWindowId(), sceneSession->GetRSVisible(), sceneSession->GetWindowMode());
11488     if (sceneSession->GetRSVisible() || sceneSession->GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
11489         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
11490 #ifdef MEMMGR_WINDOW_ENABLE
11491         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
11492 #endif
11493         sceneSession->SetRSVisible(false);
11494         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
11495         sceneSession->ClearExtWindowFlags();
11496         auto windowVisibilityInfo = new WindowVisibilityInfo(sceneSession->GetWindowId(),
11497             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
11498             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType());
11499         windowVisibilityInfo->SetAppIndex(sceneSession->GetSessionInfo().appIndex_);
11500         windowVisibilityInfo->SetBundleName(sceneSession->GetSessionInfo().bundleName_);
11501         windowVisibilityInfo->SetAbilityName(sceneSession->GetSessionInfo().abilityName_);
11502         windowVisibilityInfo->SetIsSystem(sceneSession->GetSessionInfo().isSystem_);
11503         windowVisibilityInfo->SetZOrder(sceneSession->GetZOrder());
11504         windowVisibilityInfos.emplace_back(windowVisibilityInfo);
11505 #ifdef MEMMGR_WINDOW_ENABLE
11506         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
11507             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
11508 #endif
11509         TLOGD(WmsLogTag::DEFAULT, "covered status changed window:%{public}u, isVisible:%{public}d",
11510             sceneSession->GetWindowId(), sceneSession->GetRSVisible());
11511         CheckAndNotifyWaterMarkChangedResult();
11512         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
11513 #ifdef MEMMGR_WINDOW_ENABLE
11514         TLOGD(WmsLogTag::DEFAULT, "Notify memMgrWindowInfos changed start");
11515         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
11516 #endif
11517     }
11518 }
11519 
FindSessionByToken(const sptr<IRemoteObject> & token,WindowType type)11520 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token, WindowType type)
11521 {
11522     if (token == nullptr) {
11523         TLOGW(WmsLogTag::WMS_MAIN, "token is nullptr");
11524         return nullptr;
11525     }
11526     sptr<SceneSession> session = nullptr;
11527     auto cmpFunc = [token, type](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
11528         if (pair.second == nullptr) {
11529             return false;
11530         }
11531         if (pair.second->GetWindowType() == type) {
11532             return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
11533         }
11534         return false;
11535     };
11536     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11537     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
11538     if (iter != sceneSessionMap_.end()) {
11539         session = iter->second;
11540     }
11541     return session;
11542 }
11543 
FindSessionByAffinity(const std::string & affinity)11544 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(const std::string& affinity)
11545 {
11546     if (affinity.size() == 0) {
11547         TLOGI(WmsLogTag::DEFAULT, "AbilityInfo affinity is empty");
11548         return nullptr;
11549     }
11550     sptr<SceneSession> session = nullptr;
11551     auto cmpFunc = [this, &affinity](const auto& pair) {
11552         auto sceneSession = pair.second;
11553         if (sceneSession == nullptr || !CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
11554             return false;
11555         }
11556         return sceneSession->GetSessionInfo().sessionAffinity == affinity;
11557     };
11558     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11559     if (auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
11560         iter != sceneSessionMap_.end()) {
11561         session = iter->second;
11562     }
11563     return session;
11564 }
11565 
PreloadInLakeApp(const std::string & bundleName)11566 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
11567 {
11568     TLOGD(WmsLogTag::DEFAULT, "name %{public}s", bundleName.c_str());
11569     if (auto collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE)) {
11570         TLOGI(WmsLogTag::DEFAULT, "NotifyPreloadAbility: %{public}s", bundleName.c_str());
11571         collaborator->NotifyPreloadAbility(bundleName);
11572     }
11573 }
11574 
PendingSessionToForeground(const sptr<IRemoteObject> & token)11575 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
11576 {
11577     TLOGI(WmsLogTag::WMS_LIFE, "in");
11578     auto pid = IPCSkeleton::GetCallingRealPid();
11579     if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
11580         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
11581         return WSError::WS_ERROR_INVALID_PERMISSION;
11582     }
11583 
11584     return taskScheduler_->PostSyncTask([this, &token]() {
11585         if (auto session = FindSessionByToken(token)) {
11586             return session->PendingSessionToForeground();
11587         }
11588         TLOGNE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
11589         return WSError::WS_ERROR_INVALID_PARAM;
11590     }, __func__);
11591 }
11592 
PendingSessionToBackground(const sptr<IRemoteObject> & token,const BackgroundParams & params)11593 WSError SceneSessionManager::PendingSessionToBackground(const sptr<IRemoteObject>& token,
11594     const BackgroundParams& params)
11595 {
11596     TLOGI(WmsLogTag::WMS_LIFE, "in");
11597     if (!SessionPermission::IsSACalling()) {
11598         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to background!");
11599         return WSError::WS_ERROR_INVALID_PERMISSION;
11600     }
11601     return taskScheduler_->PostSyncTask([this, &token, params] {
11602         sptr<SceneSession> session = nullptr;
11603         if (params.persistentId > INVALID_SESSION_ID) {
11604             TLOGNI(WmsLogTag::WMS_LIFE, "Find scene sesion by persistentId: %{public}d", params.persistentId);
11605             session = GetSceneSession(params.persistentId);
11606         } else if (token != nullptr) {
11607             TLOGNI(WmsLogTag::WMS_LIFE, "Find scene sesion by token");
11608             session = FindSessionByToken(token);
11609         }
11610         if (session == nullptr) {
11611             TLOGNE(WmsLogTag::WMS_LIFE, "fail to find session");
11612             return WSError::WS_ERROR_INVALID_PARAM;
11613         }
11614         return session->PendingSessionToBackground(params);
11615     }, __func__);
11616 }
11617 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)11618 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
11619     bool shouldBackToCaller)
11620 {
11621     return taskScheduler_->PostSyncTask([this, &token, shouldBackToCaller] {
11622         if (auto session = FindSessionByToken(token)) {
11623             return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
11624         }
11625         TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
11626         return WSError::WS_ERROR_INVALID_PARAM;
11627     }, __func__);
11628 }
11629 
ClearDisplayStatusBarTemporarilyFlags()11630 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
11631 {
11632     for (auto persistentId : avoidAreaListenerSessionSet_) {
11633         auto sceneSession = GetSceneSession(persistentId);
11634         if (sceneSession == nullptr) {
11635             continue;
11636         }
11637         sceneSession->SetIsDisplayStatusBarTemporarily(false);
11638     }
11639 }
11640 
GetFocusSessionToken(sptr<IRemoteObject> & token,DisplayId displayId)11641 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject>& token, DisplayId displayId)
11642 {
11643     if (!SessionPermission::IsSACalling()) {
11644         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
11645         return WSError::WS_ERROR_INVALID_PERMISSION;
11646     }
11647     return taskScheduler_->PostSyncTask([this, &token, where = __func__, displayId]() {
11648         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
11649         if (focusGroup == nullptr) {
11650             TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
11651             return WSError::WS_ERROR_INVALID_SESSION;
11652         }
11653         TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
11654             where, focusGroup->GetFocusedSessionId());
11655         if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
11656             token = sceneSession->GetAbilityToken();
11657             if (token == nullptr) {
11658                 TLOGNE(WmsLogTag::WMS_FOCUS, "token is nullptr");
11659                 return WSError::WS_ERROR_INVALID_PARAM;
11660             }
11661             return WSError::WS_OK;
11662         }
11663         return WSError::WS_ERROR_INVALID_SESSION;
11664     }, __func__);
11665 }
11666 
GetFocusSessionElement(AppExecFwk::ElementName & element,DisplayId displayId)11667 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element, DisplayId displayId)
11668 {
11669     auto pid = IPCSkeleton::GetCallingRealPid();
11670     AppExecFwk::RunningProcessInfo info;
11671     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
11672     if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
11673         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
11674         return WSError::WS_ERROR_INVALID_PERMISSION;
11675     }
11676     return taskScheduler_->PostSyncTask([this, &element, where = __func__, displayId]() {
11677         auto focusGroup = windowFocusController_->GetFocusGroup(displayId);
11678         if (focusGroup == nullptr) {
11679             TLOGNE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, displayId);
11680             return WSError::WS_ERROR_INVALID_SESSION;
11681         }
11682         TLOGND(WmsLogTag::WMS_FOCUS, "%{public}s with focusedSessionId: %{public}d",
11683             where, focusGroup->GetFocusedSessionId());
11684         if (auto sceneSession = GetSceneSession(focusGroup->GetFocusedSessionId())) {
11685             const auto& sessionInfo = sceneSession->GetSessionInfo();
11686             element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
11687                 sessionInfo.abilityName_, sessionInfo.moduleName_);
11688             return WSError::WS_OK;
11689         }
11690         return WSError::WS_ERROR_INVALID_SESSION;
11691     }, __func__);
11692 }
11693 
IsFocusWindowParent(const sptr<IRemoteObject> & token,bool & isParent)11694 WSError SceneSessionManager::IsFocusWindowParent(const sptr<IRemoteObject>& token, bool& isParent)
11695 {
11696     if (!SessionPermission::IsSACalling()) {
11697         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
11698         return WSError::WS_ERROR_INVALID_PERMISSION;
11699     }
11700     return taskScheduler_->PostSyncTask([this, &token, &isParent, where = __func__]() {
11701         std::vector<std::pair<DisplayId, int32_t>> allFocusedSessionList =
11702             windowFocusController_->GetAllFocusedSessionList();
11703         if (allFocusedSessionList.size() == 0) {
11704             TLOGNE(WmsLogTag::WMS_FOCUS, "%{public}s has no focus group",  where);
11705             return WSError::WS_ERROR_INVALID_SESSION;
11706         }
11707         for (const auto& focusState : allFocusedSessionList) {
11708             auto focusedSession = GetSceneSession(focusState.second);
11709             if (focusedSession == nullptr) {
11710                 TLOGNE(WmsLogTag::WMS_FOCUS, "%{public}s session is nullptr: %{public}d",  where, focusState.second);
11711                 return WSError::WS_ERROR_INVALID_SESSION;
11712             }
11713             if (focusedSession->GetAbilityToken() == token || focusedSession->HasParentSessionWithToken(token)) {
11714                 isParent = true;
11715                 return WSError::WS_OK;
11716             }
11717         }
11718         isParent = false;
11719         return WSError::WS_OK;
11720     }, __func__);
11721 }
11722 
UpdateSessionAvoidAreaListener(int32_t persistentId,bool haveListener)11723 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t persistentId, bool haveListener)
11724 {
11725     const auto callingPid = IPCSkeleton::GetCallingRealPid();
11726     auto task = [this, persistentId, haveListener, callingPid, where = __func__]() {
11727         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s win %{public}d haveListener %{public}d",
11728             where, persistentId, haveListener);
11729         auto sceneSession = GetSceneSession(persistentId);
11730         if (sceneSession == nullptr) {
11731             TLOGND(WmsLogTag::WMS_IMMS, "%{public}s sceneSession is nullptr", where);
11732             return WSError::WS_DO_NOTHING;
11733         }
11734         if (callingPid != sceneSession->GetCallingPid()) {
11735             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s Permission denied, not called by the same process", where);
11736             return WSError::WS_ERROR_INVALID_PERMISSION;
11737         }
11738         if (haveListener) {
11739             avoidAreaListenerSessionSet_.insert(persistentId);
11740             UpdateAvoidArea(persistentId);
11741         } else {
11742             avoidAreaListenerSessionSet_.erase(persistentId);
11743         }
11744         return WSError::WS_OK;
11745     };
11746     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
11747 }
11748 
UpdateSessionScreenshotAppEventListener(int32_t persistentId,bool haveListener)11749 WMError SceneSessionManager::UpdateSessionScreenshotAppEventListener(int32_t persistentId, bool haveListener)
11750 {
11751     return taskScheduler_->PostSyncTask([this, persistentId, haveListener, where = __func__]() {
11752         TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d haveListener: %{public}u",
11753             where, persistentId, haveListener);
11754         auto sceneSession = GetSceneSession(persistentId);
11755         if (sceneSession == nullptr) {
11756             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d sceneSession is nullptr", where, persistentId);
11757             return WMError::WM_ERROR_NULLPTR;
11758         }
11759         if (haveListener) {
11760             screenshotAppEventListenerSessionSet_.insert(persistentId);
11761         } else {
11762             screenshotAppEventListenerSessionSet_.erase(persistentId);
11763         }
11764         return WMError::WM_OK;
11765     }, __func__);
11766 }
11767 
UpdateAvoidSessionAvoidArea(WindowType type)11768 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type)
11769 {
11770     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
11771         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
11772     AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(avoidType);
11773     rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
11774 
11775     for (auto persistentId : avoidAreaListenerSessionSet_) {
11776         auto sceneSession = GetSceneSession(persistentId);
11777         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
11778             continue;
11779         }
11780         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(avoidType);
11781         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
11782     }
11783 }
11784 
UpdateNormalSessionAvoidArea(int32_t persistentId,const sptr<SceneSession> & sceneSession,bool & needUpdate)11785 void SceneSessionManager::UpdateNormalSessionAvoidArea(
11786     int32_t persistentId, const sptr<SceneSession>& sceneSession, bool& needUpdate)
11787 {
11788     if (rootSceneSession_->GetPersistentId() == persistentId) {
11789         UpdateRootSceneSessionAvoidArea(persistentId, needUpdate);
11790         return;
11791     }
11792     if (sceneSession == nullptr) {
11793         TLOGE(WmsLogTag::WMS_IMMS, "session is nullptr, win %{public}d", persistentId);
11794         needUpdate = false;
11795         return;
11796     }
11797     if (!IsSessionVisibleForeground(sceneSession)) {
11798         TLOGI(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u sessionState %{public}u",
11799             persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
11800         needUpdate = false;
11801         return;
11802     }
11803     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
11804         TLOGD(WmsLogTag::WMS_IMMS,
11805             "win %{public}d not in avoidAreaListenerNodes, cannot update avoid area", persistentId);
11806         needUpdate = false;
11807         return;
11808     }
11809     sceneSession->UpdateSizeChangeReason(SizeChangeReason::AVOID_AREA_CHANGE);
11810     sceneSession->NotifyClientToUpdateRect("AvoidAreaChange", nullptr);
11811 }
11812 
UpdateRootSceneSessionAvoidArea(int32_t persistentId,bool & needUpdate)11813 void SceneSessionManager::UpdateRootSceneSessionAvoidArea(int32_t persistentId, bool& needUpdate)
11814 {
11815     using T = std::underlying_type_t<AvoidAreaType>;
11816     for (T avoidAreaType = static_cast<T>(AvoidAreaType::TYPE_START);
11817         avoidAreaType < static_cast<T>(AvoidAreaType::TYPE_END); avoidAreaType++) {
11818         AvoidArea avoidArea = rootSceneSession_->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidAreaType));
11819         if (avoidAreaType == static_cast<T>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
11820             !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
11821                 rootSceneSession_->GetSessionRect().height_)) {
11822             continue;
11823         }
11824         rootSceneSession_->UpdateAvoidArea(new AvoidArea(avoidArea), static_cast<AvoidAreaType>(avoidAreaType));
11825     }
11826     needUpdate = true;
11827 }
11828 
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)11829 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
11830 {
11831     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
11832     auto sceneSession = GetSceneSession(windowId);
11833     if (sceneSession == nullptr) {
11834         TLOGW(WmsLogTag::WMS_EVENT, "window not exist: %{public}d", windowId);
11835         return;
11836     }
11837 
11838     TLOGI(WmsLogTag::WMS_EVENT, "Notify window:%{public}d, pid:%{public}d", windowId, pid);
11839     taskScheduler_->PostAsyncTask([weakSceneSession = wptr<SceneSession>(sceneSession), startMoving] {
11840         auto sceneSession = weakSceneSession.promote();
11841         if (sceneSession == nullptr) {
11842             TLOGNW(WmsLogTag::WMS_EVENT, "session is null");
11843             return;
11844         }
11845         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(sceneSession, startMoving);
11846     }, __func__);
11847 }
11848 
UpdateAvoidArea(int32_t persistentId)11849 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
11850 {
11851     taskScheduler_->PostAsyncTask([this, persistentId] {
11852         bool needUpdate = false;
11853         auto sceneSession = GetSceneSession(persistentId);
11854         if (sceneSession != nullptr && sceneSession->IsImmersiveType()) {
11855             UpdateAvoidSessionAvoidArea(sceneSession->GetWindowType());
11856         } else {
11857             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
11858         }
11859         if (needUpdate) {
11860             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
11861         }
11862     }, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
11863 }
11864 
GetKeyboardOccupiedAreaWithRotation(int32_t persistentId,Rotation rotation,std::vector<std::pair<bool,WSRect>> & avoidAreas)11865 void SceneSessionManager::GetKeyboardOccupiedAreaWithRotation(
11866     int32_t persistentId, Rotation rotation, std::vector<std::pair<bool, WSRect>>& avoidAreas)
11867 {
11868     if (systemConfig_.IsPcWindow()) {
11869         TLOGE(WmsLogTag::WMS_KEYBOARD, "The PC device is not compatible, id: %{public}d", persistentId);
11870         return;
11871     }
11872 
11873     auto sceneSession = GetSceneSession(persistentId);
11874     if (sceneSession == nullptr) {
11875         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is nullptr, id: %{public}d", persistentId);
11876         return;
11877     }
11878     auto keyboardSession = GetKeyboardSession(sceneSession->GetSessionProperty()->GetDisplayId(), false);
11879     if (keyboardSession == nullptr) {
11880         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr, id: %{public}d", persistentId);
11881         return;
11882     }
11883 
11884     std::pair<bool, WSRect> keyboardOccupiedArea = {true, {0, 0, 0, 0}};
11885     const KeyboardLayoutParams& keyboardLayoutParams = keyboardSession->GetSessionProperty()->GetKeyboardLayoutParams();
11886     Rect nextRect;
11887     if (rotation == Rotation::ROTATION_0 || rotation == Rotation::ROTATION_180) {
11888         nextRect = keyboardLayoutParams.PortraitPanelRect_;
11889     } else if (rotation == Rotation::ROTATION_90 || rotation == Rotation::ROTATION_270) {
11890         nextRect = keyboardLayoutParams.LandscapePanelRect_;
11891     } else {
11892         TLOGE(WmsLogTag::WMS_KEYBOARD,
11893             "Rotation is invalid, id: %{public}d, rotation: %{public}u", persistentId, rotation);
11894         return;
11895     }
11896     keyboardOccupiedArea.second = {
11897         nextRect.posX_, nextRect.posY_, static_cast<int32_t>(nextRect.width_), static_cast<int32_t>(nextRect.height_)
11898     };
11899 
11900     if (!keyboardSession->IsSessionForeground() ||
11901         keyboardLayoutParams.gravity_ == WindowGravity::WINDOW_GRAVITY_FLOAT) {
11902         keyboardOccupiedArea.first = false;
11903     }
11904     TLOGI(WmsLogTag::WMS_KEYBOARD, "next keyboardOccupiedArea: [%{public}d, %{public}s]", keyboardOccupiedArea.first,
11905         keyboardOccupiedArea.second.ToString().c_str());
11906     avoidAreas.emplace_back(keyboardOccupiedArea);
11907 }
11908 
UpdateGestureBackEnabled(int32_t persistentId)11909 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
11910 {
11911     auto task = [this, persistentId, where = __func__] {
11912         auto sceneSession = GetSceneSession(persistentId);
11913         if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
11914             TLOGND(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable");
11915             return;
11916         }
11917         auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
11918         if (needEnableGestureBack) {
11919             gestureBackEnableWindowIdSet_.erase(persistentId);
11920         } else {
11921             gestureBackEnableWindowIdSet_.insert(persistentId);
11922         }
11923         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
11924             sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
11925             (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
11926              sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
11927             enterRecent_.load() || !sceneSession->IsFocused()) {
11928             needEnableGestureBack = true;
11929         }
11930         if (gestureNavigationEnabledChangeFunc_ != nullptr) {
11931             gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
11932                 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
11933         } else {
11934             TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s callback func is null", where);
11935         }
11936     };
11937     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
11938 }
11939 
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)11940 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
11941 {
11942     TLOGD(WmsLogTag::WMS_IMMS, "win %{public}u isVisible %{public}u",
11943         persistentId, isVisible);
11944     taskScheduler_->PostTask([this, persistentId, isVisible] {
11945         auto sceneSession = GetSceneSession(persistentId);
11946         if (sceneSession == nullptr) {
11947             TLOGNE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
11948             return;
11949         }
11950         sceneSession->SetIsStatusBarVisible(isVisible);
11951     }, __func__);
11952     return WSError::WS_OK;
11953 }
11954 
NotifyStatusBarConstantlyShow(DisplayId displayId,bool isVisible)11955 void SceneSessionManager::NotifyStatusBarConstantlyShow(DisplayId displayId, bool isVisible)
11956 {
11957     TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " isVisible %{public}u", displayId, isVisible);
11958     const char* const where = __func__;
11959     auto task = [this, displayId, isVisible] {
11960         statusBarConstantlyShowMap_[displayId] = isVisible;
11961         UpdateRootSceneAvoidArea();
11962         return WMError::WM_OK;
11963     };
11964     taskScheduler_->PostAsyncTask(task, where);
11965 }
11966 
GetStatusBarConstantlyShow(DisplayId displayId,bool & isVisible) const11967 void SceneSessionManager::GetStatusBarConstantlyShow(DisplayId displayId, bool& isVisible) const
11968 {
11969     auto it = statusBarConstantlyShowMap_.find(displayId);
11970     if (it != statusBarConstantlyShowMap_.end()) {
11971         isVisible = it->second;
11972     } else {
11973         isVisible = false;
11974     }
11975 }
11976 
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)11977 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
11978 {
11979     TLOGI(WmsLogTag::WMS_IMMS, "isVisible %{public}u "
11980         "area %{public}s, displayId %{public}" PRIu64, isVisible, barArea.ToString().c_str(), displayId);
11981     taskScheduler_->PostAsyncTask([this, isVisible, barArea, displayId, where = __func__] {
11982         bool isNeedUpdate = true;
11983         {
11984             std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
11985             isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
11986                 currAINavigationBarAreaMap_.count(displayId) == 0 ||
11987                 currAINavigationBarAreaMap_[displayId] != barArea;
11988             if (isNeedUpdate) {
11989                 isAINavigationBarVisible_ = isVisible;
11990                 currAINavigationBarAreaMap_.clear();
11991                 currAINavigationBarAreaMap_[displayId] = barArea;
11992             }
11993             if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
11994                 TLOGND(WmsLogTag::WMS_IMMS, "%{public}s barArea should be empty if invisible", where);
11995                 currAINavigationBarAreaMap_[displayId] = WSRect();
11996             }
11997         }
11998         if (isNeedUpdate) {
11999             TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s isVisible %{public}u bar area %{public}s",
12000                 where, isVisible, barArea.ToString().c_str());
12001             for (auto persistentId : avoidAreaListenerSessionSet_) {
12002                 NotifySessionAINavigationBarChange(persistentId);
12003             }
12004             rootSceneSession_->UpdateAvoidArea(
12005                 new AvoidArea(rootSceneSession_->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR)),
12006                 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
12007         }
12008     }, __func__);
12009     return WSError::WS_OK;
12010 }
12011 
NotifyNextAvoidRectInfo(AvoidAreaType type,const WSRect & portraitRect,const WSRect & landspaceRect,DisplayId displayId)12012 WSError SceneSessionManager::NotifyNextAvoidRectInfo(AvoidAreaType type,
12013     const WSRect& portraitRect, const WSRect& landspaceRect, DisplayId displayId)
12014 {
12015     TLOGD(WmsLogTag::WMS_IMMS, "type %{public}d "
12016         "portraitRect %{public}s, portraitRect %{public}s, displayId %{public}" PRIu64,
12017         type, portraitRect.ToString().c_str(), landspaceRect.ToString().c_str(), displayId);
12018     std::lock_guard<std::mutex> lock(nextAvoidRectInfoMapMutex_);
12019     nextAvoidRectInfoMap_[type][displayId] = { portraitRect, landspaceRect };
12020     return WSError::WS_OK;
12021 }
12022 
GetNextAvoidRectInfo(DisplayId displayId,AvoidAreaType type,std::pair<WSRect,WSRect> & nextSystemBarAvoidAreaRectInfo)12023 WSError SceneSessionManager::GetNextAvoidRectInfo(DisplayId displayId, AvoidAreaType type,
12024     std::pair<WSRect, WSRect>& nextSystemBarAvoidAreaRectInfo)
12025 {
12026     {
12027         std::lock_guard<std::mutex> lock(nextAvoidRectInfoMapMutex_);
12028         if (nextAvoidRectInfoMap_.count(type) == 0 || nextAvoidRectInfoMap_[type].count(displayId) == 0) {
12029             TLOGI(WmsLogTag::WMS_IMMS, "get failed, type %{public}d displayId %{public}" PRIu64, type, displayId);
12030             return WSError::WS_DO_NOTHING;
12031         }
12032         nextSystemBarAvoidAreaRectInfo = nextAvoidRectInfoMap_[type][displayId];
12033     }
12034     return WSError::WS_OK;
12035 }
12036 
NotifySessionAINavigationBarChange(int32_t persistentId)12037 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
12038 {
12039     auto sceneSession = GetSceneSession(persistentId);
12040     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
12041         TLOGD(WmsLogTag::WMS_IMMS, "scene session is nullptr or not visible");
12042         return;
12043     }
12044     sceneSession->HandleLayoutAvoidAreaUpdate(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
12045 }
12046 
GetAINavigationBarArea(uint64_t displayId)12047 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
12048 {
12049     std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
12050     if (currAINavigationBarAreaMap_.count(displayId) == 0) {
12051         return {};
12052     }
12053     return currAINavigationBarAreaMap_[displayId];
12054 }
12055 
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)12056 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
12057 {
12058     const auto callingPid = IPCSkeleton::GetCallingRealPid();
12059     auto task = [this, persistentId, haveListener, callingPid]() {
12060         TLOGNI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
12061             persistentId, haveListener);
12062         auto sceneSession = GetSceneSession(persistentId);
12063         if (sceneSession == nullptr) {
12064             TLOGNE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
12065             return WSError::WS_DO_NOTHING;
12066         }
12067         if (callingPid != sceneSession->GetCallingPid()) {
12068             TLOGNE(WmsLogTag::WMS_EVENT, "Permission denied");
12069             return WSError::WS_ERROR_INVALID_PERMISSION;
12070         }
12071         if (haveListener) {
12072             touchOutsideListenerSessionSet_.insert(persistentId);
12073         } else {
12074             touchOutsideListenerSessionSet_.erase(persistentId);
12075         }
12076         return WSError::WS_OK;
12077     };
12078     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
12079 }
12080 
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)12081 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
12082 {
12083     const auto callingPid = IPCSkeleton::GetCallingRealPid();
12084     return taskScheduler_->PostSyncTask([this, persistentId, haveListener, callingPid]() -> WSError {
12085         TLOGNI(WmsLogTag::WMS_LIFE, "persistentId: %{public}d haveListener:%{public}d",
12086             persistentId, haveListener);
12087         auto sceneSession = GetSceneSession(persistentId);
12088         if (sceneSession == nullptr) {
12089             TLOGND(WmsLogTag::WMS_LIFE, "sceneSession is nullptr.");
12090             return haveListener ? WSError::WS_DO_NOTHING : WSError::WS_OK;
12091         }
12092         if (callingPid != sceneSession->GetCallingPid()) {
12093             TLOGNE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
12094             return WSError::WS_ERROR_INVALID_PERMISSION;
12095         }
12096         if (haveListener) {
12097             windowVisibilityListenerSessionSet_.insert(persistentId);
12098             sceneSession->NotifyWindowVisibility();
12099         } else {
12100             windowVisibilityListenerSessionSet_.erase(persistentId);
12101         }
12102         return WSError::WS_OK;
12103     }, __func__);
12104 }
12105 
UpdateDarkColorModeToRS()12106 void SceneSessionManager::UpdateDarkColorModeToRS()
12107 {
12108     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
12109     if (appContext == nullptr) {
12110         TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
12111         return;
12112     }
12113     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
12114     if (config == nullptr) {
12115         TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
12116         return;
12117     }
12118     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
12119     bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
12120     bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
12121     TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d", colorMode.c_str(), ret);
12122 }
12123 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)12124 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
12125 {
12126     processVirtualPixelRatioChangeFunc_ = func;
12127     TLOGI(WmsLogTag::DEFAULT, "end");
12128 }
12129 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)12130 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
12131     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
12132 {
12133     if (displayInfo == nullptr) {
12134         TLOGE(WmsLogTag::DEFAULT, "displayInfo is nullptr.");
12135         return;
12136     }
12137     taskScheduler_->PostSyncTask([this, displayInfo, type, where = __func__]() {
12138         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
12139             type == DisplayStateChangeType::RESOLUTION_CHANGE &&
12140             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
12141             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
12142                           displayInfo->GetWidth(), displayInfo->GetHeight() };
12143             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
12144         }
12145         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12146         for (const auto& [_, sceneSession] : sceneSessionMap_) {
12147             if (sceneSession == nullptr) {
12148                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s null scene session", where);
12149                 continue;
12150             }
12151             if (sceneSession->GetSessionProperty()->GetDisplayId() != displayInfo->GetDisplayId()) {
12152                 continue;
12153             }
12154             if (sceneSession->GetSessionInfo().isSystem_) {
12155                 continue;
12156             }
12157             if (sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
12158                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE) {
12159                 sceneSession->UpdateDensity();
12160                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "UpdateDensity name=%{public}s, persistentId=%{public}d, "
12161                     "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
12162                     sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
12163                     sceneSession->GetSessionState(), sceneSession->IsVisible());
12164             } else if (sceneSession->GetSessionState() == SessionState::STATE_BACKGROUND && systemConfig_.IsPcWindow()) {
12165                 sceneSession->SaveLastDensity();
12166                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "SaveLastDensity name=%{public}s, persistentId=%{public}d, "
12167                     "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
12168                     sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
12169                     sceneSession->GetSessionState(), sceneSession->IsVisible());
12170             }
12171         }
12172         UpdateDisplayRegion(displayInfo);
12173         return WSError::WS_OK;
12174     }, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
12175 }
12176 
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)12177 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
12178     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
12179 {
12180     if (displayInfo == nullptr) {
12181         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr.");
12182         return;
12183     }
12184     taskScheduler_->PostSyncTask([this, displayInfo, where = __func__]() {
12185         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12186         for (const auto& [_, sceneSession] : sceneSessionMap_) {
12187             if (sceneSession == nullptr) {
12188                 TLOGNE(WmsLogTag::DMS, "%{public}s null scene session", where);
12189                 continue;
12190             }
12191             if (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
12192                 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) {
12193                 continue;
12194             }
12195             if (NearEqual(sceneSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
12196                 NearEqual(sceneSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
12197                 sceneSession->GetRotation() != displayInfo->GetRotation()) {
12198                 sceneSession->UpdateRotationAvoidArea();
12199                 TLOGND(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
12200                     "winType=%{public}d, state=%{public}d, visible-%{public}d", sceneSession->GetWindowName().c_str(),
12201                     sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState(),
12202                     sceneSession->IsVisible());
12203             }
12204             sceneSession->SetRotation(displayInfo->GetRotation());
12205             sceneSession->UpdateOrientation();
12206         }
12207         UpdateDisplayRegion(displayInfo);
12208         return WSError::WS_OK;
12209     }, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
12210 }
12211 
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)12212 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
12213 {
12214     if (displayInfo == nullptr) {
12215         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
12216         return;
12217     }
12218 
12219     taskScheduler_->PostAsyncTask([this, displayInfo] {
12220         ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
12221             displayInfo->GetScaleX(),
12222             displayInfo->GetScaleY(),
12223             displayInfo->GetPivotX(),
12224             displayInfo->GetPivotY(),
12225             displayInfo->GetTranslateX(),
12226             displayInfo->GetTranslateY());
12227         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
12228         FlushWindowInfoToMMI(true);
12229     }, __func__);
12230 }
12231 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)12232 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
12233     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
12234 {
12235     TLOGD(WmsLogTag::DEFAULT, "type: %{public}u", type);
12236     switch (type) {
12237         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
12238             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
12239                 displayInfo, displayInfoMap, type);
12240             SceneSessionManager::GetInstance().FlushWindowInfoToMMI();
12241             break;
12242         }
12243         case DisplayStateChangeType::UPDATE_ROTATION: {
12244             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
12245                 displayInfo, displayInfoMap, type);
12246             break;
12247         }
12248         case DisplayStateChangeType::UPDATE_SCALE: {
12249             SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
12250             break;
12251         }
12252         default:
12253             return;
12254     }
12255 }
12256 
CheckIfNeedMultipleFocus(const std::string & name,const ScreenType & screenType)12257 bool CheckIfNeedMultipleFocus(const std::string& name, const ScreenType& screenType)
12258 {
12259     if (screenType == ScreenType::VIRTUAL && (name == "CeliaView" || name == "DevEcoViewer")) {
12260         return true;
12261     }
12262     return false;
12263 }
12264 
OnScreenConnected(const sptr<ScreenSession> & screenSession)12265 void ScreenConnectionChangeListener::OnScreenConnected(const sptr<ScreenSession>& screenSession)
12266 {
12267     if (screenSession == nullptr) {
12268         TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
12269         return;
12270     }
12271     TLOGI(WmsLogTag::WMS_FOCUS,
12272           "name: %{public}s, screenId: %{public}" PRIu64 ", displayGroupId: %{public}" PRIu64
12273           " ,screenType: %{public}u",
12274           screenSession->GetName().c_str(),
12275           screenSession->GetScreenId(),
12276           screenSession->GetDisplayGroupId(),
12277           screenSession->GetScreenProperty().GetScreenType());
12278     if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
12279         SceneSessionManager::GetInstance().AddFocusGroup(screenSession->GetDisplayGroupId(),
12280                                                          screenSession->GetScreenId());
12281     }
12282 
12283     // Window Layout Global Coordinate System: monitors screen position changes in the global coordinate system
12284     screenSession->RegisterScreenChangeListener(&SceneScreenChangeListener::GetInstance());
12285 }
12286 
OnScreenDisconnected(const sptr<ScreenSession> & screenSession)12287 void ScreenConnectionChangeListener::OnScreenDisconnected(const sptr<ScreenSession>& screenSession)
12288 {
12289     if (screenSession == nullptr) {
12290         TLOGE(WmsLogTag::WMS_FOCUS, "screenSession is nullptr");
12291         return;
12292     }
12293     TLOGI(WmsLogTag::WMS_FOCUS,
12294           "name: %{public}s, screenId: %{public}" PRIu64 ", displayGroupId: %{public}" PRIu64
12295           " ,screenType: %{public}u",
12296           screenSession->GetName().c_str(),
12297           screenSession->GetScreenId(),
12298           screenSession->GetDisplayGroupId(),
12299           screenSession->GetScreenProperty().GetScreenType());
12300     if (CheckIfNeedMultipleFocus(screenSession->GetName(), screenSession->GetScreenProperty().GetScreenType())) {
12301         SceneSessionManager::GetInstance().RemoveFocusGroup(screenSession->GetDisplayGroupId(),
12302                                                             screenSession->GetScreenId());
12303     }
12304 
12305     // Window Layout Global Coordinate System
12306     screenSession->UnregisterScreenChangeListener(&SceneScreenChangeListener::GetInstance());
12307 }
12308 
OnScreenshot(DisplayId displayId)12309 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
12310 {
12311     SceneSessionManager::GetInstance().OnScreenshot(displayId);
12312 }
12313 
OnScreenshot(DisplayId displayId)12314 void SceneSessionManager::OnScreenshot(DisplayId displayId)
12315 {
12316     taskScheduler_->PostAsyncTask([this, displayId]() {
12317         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12318         for (const auto& [_, sceneSession] : sceneSessionMap_) {
12319             if (sceneSession == nullptr) {
12320                 continue;
12321             }
12322             auto state = sceneSession->GetSessionState();
12323             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
12324                 sceneSession->NotifyScreenshot();
12325             }
12326         }
12327     }, "OnScreenshot:PID:" + std::to_string(displayId));
12328 }
12329 
NotifyScreenshotEvent(ScreenshotEventType type)12330 WMError SceneSessionManager::NotifyScreenshotEvent(ScreenshotEventType type)
12331 {
12332     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "event: %{public}d", type);
12333     if (!SessionPermission::IsSystemCalling()) {
12334         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
12335         return WMError::WM_ERROR_NOT_SYSTEM_APP;
12336     }
12337     taskScheduler_->PostAsyncTask([this, type, where = __func__] {
12338         for (auto persistentId : screenshotAppEventListenerSessionSet_) {
12339             auto sceneSession = GetSceneSession(persistentId);
12340             if (sceneSession == nullptr) {
12341                 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d session is null", where, persistentId);
12342                 continue;
12343             }
12344             auto state = sceneSession->GetSessionState();
12345             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s win: %{public}d, state: %{public}u, event: %{public}d",
12346                 where, sceneSession->GetPersistentId(), state, type);
12347             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
12348                 sceneSession->NotifyScreenshotAppEvent(type);
12349             }
12350         }
12351     }, __func__);
12352     return WMError::WM_OK;
12353 }
12354 
ClearSession(int32_t persistentId)12355 WSError SceneSessionManager::ClearSession(int32_t persistentId)
12356 {
12357     TLOGI(WmsLogTag::WMS_LIFE, "id: %{public}d", persistentId);
12358     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12359         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12360         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12361     }
12362     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12363         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12364         return WSError::WS_ERROR_INVALID_PERMISSION;
12365     }
12366     taskScheduler_->PostAsyncTask([this, persistentId]() {
12367         auto sceneSession = GetSceneSession(persistentId);
12368         return ClearSession(sceneSession);
12369     }, "ClearSession:PID:" + std::to_string(persistentId));
12370     return WSError::WS_OK;
12371 }
12372 
ClearSession(sptr<SceneSession> sceneSession)12373 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
12374 {
12375     TLOGD(WmsLogTag::WMS_LIFE, "in");
12376     if (sceneSession == nullptr) {
12377         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
12378         return WSError::WS_ERROR_INVALID_SESSION;
12379     }
12380     if (!IsSessionClearable(sceneSession)) {
12381         TLOGE(WmsLogTag::WMS_LIFE, "session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
12382         return WSError::WS_ERROR_INVALID_SESSION;
12383     }
12384     const WSError errCode = sceneSession->Clear(false, true);
12385     return errCode;
12386 }
12387 
ClearAllSessions()12388 WSError SceneSessionManager::ClearAllSessions()
12389 {
12390     TLOGD(WmsLogTag::WMS_LIFE, "in");
12391     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12392         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12393         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12394     }
12395     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12396         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12397         return WSError::WS_ERROR_INVALID_PERMISSION;
12398     }
12399     auto task = [this]() {
12400         std::vector<sptr<SceneSession>> sessionVector;
12401         GetAllClearableSessions(sessionVector);
12402         for (uint32_t i = 0; i < sessionVector.size(); i++) {
12403             ClearSession(sessionVector[i]);
12404         }
12405         return WSError::WS_OK;
12406     };
12407     taskScheduler_->PostAsyncTask(task, __func__);
12408     return WSError::WS_OK;
12409 }
12410 
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)12411 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
12412 {
12413     TLOGD(WmsLogTag::WMS_LIFE, "in");
12414     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12415     for (const auto& [_, sceneSession] : sceneSessionMap_) {
12416         if (IsSessionClearable(sceneSession)) {
12417             sessionVector.push_back(sceneSession);
12418         }
12419     }
12420 }
12421 
LockSession(int32_t sessionId)12422 WSError SceneSessionManager::LockSession(int32_t sessionId)
12423 {
12424     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
12425     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12426         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
12427         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12428     }
12429     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12430         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12431         return WSError::WS_ERROR_INVALID_PERMISSION;
12432     }
12433     const char* const where = __func__;
12434     auto task = [this, sessionId, where]() {
12435         auto sceneSession = GetSceneSession(sessionId);
12436         if (sceneSession == nullptr) {
12437             TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s cannot find session, id: %{public}d", where, sessionId);
12438             return WSError::WS_ERROR_INVALID_PARAM;
12439         }
12440         sceneSession->SetSessionInfoLockedState(true);
12441         return WSError::WS_OK;
12442     };
12443     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
12444 }
12445 
UnlockSession(int32_t sessionId)12446 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
12447 {
12448     TLOGI(WmsLogTag::DEFAULT, "id: %{public}d", sessionId);
12449     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12450         TLOGE(WmsLogTag::DEFAULT, "The caller is not system-app, can not use system-api");
12451         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12452     }
12453     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12454         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12455         return WSError::WS_ERROR_INVALID_PERMISSION;
12456     }
12457     const char* const where = __func__;
12458     auto task = [this, sessionId, where]() {
12459         auto sceneSession = GetSceneSession(sessionId);
12460         if (sceneSession == nullptr) {
12461             TLOGNE(WmsLogTag::DEFAULT, "%{public}s cannot find session, id: %{public}d", where, sessionId);
12462             return WSError::WS_ERROR_INVALID_PARAM;
12463         }
12464         sceneSession->SetSessionInfoLockedState(false);
12465         return WSError::WS_OK;
12466     };
12467     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
12468 }
12469 
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)12470 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
12471 {
12472     TLOGI(WmsLogTag::WMS_LIFE, "in");
12473     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12474         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12475         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12476     }
12477     if (!SessionPermission::VerifySessionPermission()) {
12478         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12479         return WSError::WS_ERROR_INVALID_PERMISSION;
12480     }
12481 
12482     return WSError::WS_OK;
12483 }
12484 
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)12485 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
12486     std::vector<int32_t>& result)
12487 {
12488     TLOGI(WmsLogTag::WMS_LIFE, "in");
12489     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
12490         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
12491         return WSError::WS_ERROR_NOT_SYSTEM_APP;
12492     }
12493     if (!SessionPermission::VerifySessionPermission()) {
12494         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12495         return WSError::WS_ERROR_INVALID_PERMISSION;
12496     }
12497 
12498     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
12499     return WSError::WS_OK;
12500 }
12501 
IsSessionClearable(sptr<SceneSession> sceneSession)12502 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> sceneSession)
12503 {
12504     if (sceneSession == nullptr) {
12505         TLOGI(WmsLogTag::WMS_MAIN, "sceneSession is nullptr");
12506         return false;
12507     }
12508     const auto& sessionInfo = sceneSession->GetSessionInfo();
12509     if (sessionInfo.abilityInfo == nullptr) {
12510         TLOGI(WmsLogTag::WMS_MAIN, "sceneSession abilityInfo is nullptr");
12511         return false;
12512     }
12513     if (sessionInfo.abilityInfo->excludeFromMissions && !sceneSession->IsAnco()) {
12514         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is excludeFromMissions", sceneSession->GetPersistentId());
12515         return false;
12516     }
12517     if (sessionInfo.abilityInfo->unclearableMission) {
12518         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is unclearable", sceneSession->GetPersistentId());
12519         return false;
12520     }
12521     if (sessionInfo.isSystem_) {
12522         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is system app", sceneSession->GetPersistentId());
12523         return false;
12524     }
12525     if (sessionInfo.lockedState) {
12526         TLOGI(WmsLogTag::WMS_MAIN, "persistentId %{public}d is in lockedState", sceneSession->GetPersistentId());
12527         return false;
12528     }
12529 
12530     return true;
12531 }
12532 
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)12533 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
12534     const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
12535 {
12536     TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
12537     auto isSaCall = SessionPermission::IsSACalling();
12538     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12539         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
12540         return WSError::WS_ERROR_INVALID_PERMISSION;
12541     }
12542     if (!CheckCollaboratorType(type)) {
12543         TLOGW(WmsLogTag::DEFAULT, "collaborator register failed, invalid type.");
12544         return WSError::WS_ERROR_INVALID_TYPE;
12545     }
12546     if (impl == nullptr) {
12547         TLOGE(WmsLogTag::DEFAULT, "Collaborator is nullptr");
12548         return WSError::WS_ERROR_NULLPTR;
12549     }
12550     if (impl->AsObject() == nullptr || !impl->AsObject()->AddDeathRecipient(collaboratorDeathRecipient_)) {
12551         TLOGE(WmsLogTag::DEFAULT, "Failed to add collaborator death recipient");
12552         return WSError::WS_ERROR_IPC_FAILED;
12553     }
12554     {
12555         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
12556         collaboratorMap_[type] = impl;
12557     }
12558     auto task = [this] {
12559         if (abilityManagerCollaboratorRegisteredFunc_) {
12560             abilityManagerCollaboratorRegisteredFunc_();
12561         }
12562     };
12563     taskScheduler_->PostTask(task, __func__);
12564     return WSError::WS_OK;
12565 }
12566 
UnregisterIAbilityManagerCollaborator(int32_t type)12567 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
12568 {
12569     TLOGI(WmsLogTag::DEFAULT, "type: %{public}d", type);
12570     auto isSaCall = SessionPermission::IsSACalling();
12571     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12572         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
12573         return WSError::WS_ERROR_INVALID_PERMISSION;
12574     }
12575     if (!CheckCollaboratorType(type)) {
12576         TLOGE(WmsLogTag::DEFAULT, "collaborator unregister failed, invalid type.");
12577         return WSError::WS_ERROR_INVALID_TYPE;
12578     }
12579     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(type);
12580     if (collaborator != nullptr && collaborator->AsObject() != nullptr) {
12581         TLOGI(WmsLogTag::DEFAULT, "Remove collaborator death recipient");
12582         collaborator->AsObject()->RemoveDeathRecipient(collaboratorDeathRecipient_);
12583     }
12584     {
12585         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
12586         collaboratorMap_.erase(type);
12587     }
12588     return WSError::WS_OK;
12589 }
12590 
ClearAllCollaboratorSessions()12591 void SceneSessionManager::ClearAllCollaboratorSessions()
12592 {
12593     TLOGI(WmsLogTag::WMS_MAIN, "in");
12594     std::vector<sptr<SceneSession>> collaboratorSessions;
12595     {
12596         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12597         for (const auto& [_, sceneSession] : sceneSessionMap_) {
12598             if (sceneSession != nullptr && CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
12599                 collaboratorSessions.push_back(sceneSession);
12600             }
12601         }
12602     }
12603     for (const auto& sceneSession : collaboratorSessions) {
12604         sceneSession->Clear();
12605     }
12606 }
12607 
CheckCollaboratorType(int32_t type)12608 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
12609 {
12610     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
12611         TLOGD(WmsLogTag::WMS_MAIN, "type is invalid");
12612         return false;
12613     }
12614     return true;
12615 }
12616 
CheckIfReuseSession(SessionInfo & sessionInfo)12617 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
12618 {
12619     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
12620         sessionInfo.moduleName_);
12621     if (abilityInfo == nullptr) {
12622         TLOGE(WmsLogTag::DEFAULT, "abilityInfo is nullptr!");
12623         return BrokerStates::BROKER_UNKOWN;
12624     }
12625     sessionInfo.abilityInfo = abilityInfo;
12626     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
12627     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
12628         collaboratorType = CollaboratorType::RESERVE_TYPE;
12629     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
12630         collaboratorType = CollaboratorType::OTHERS_TYPE;
12631     }
12632     if (!CheckCollaboratorType(collaboratorType)) {
12633         TLOGW(WmsLogTag::DEFAULT, "checked not collaborator!");
12634         return BrokerStates::BROKER_UNKOWN;
12635     }
12636     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
12637     sessionInfo.collaboratorType_ = collaboratorType;
12638     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
12639     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
12640         TLOGI(WmsLogTag::DEFAULT, "FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
12641         sessionInfo.reuse = true;
12642     } else {
12643         sessionInfo.reuse = false;
12644     }
12645     TLOGI(WmsLogTag::DEFAULT, "end: affinity %{public}s type %{public}d reuse %{public}d",
12646         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
12647     return resultValue;
12648 }
12649 
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)12650 BrokerStates SceneSessionManager::NotifyStartAbility(
12651     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
12652 {
12653     TLOGI(WmsLogTag::WMS_LIFE, "type %{public}d id %{public}d windowMode %{public}d",
12654         collaboratorType, persistentId, sessionInfo.windowMode);
12655     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
12656     if (collaborator == nullptr) {
12657         return BrokerStates::BROKER_UNKOWN;
12658     }
12659     if (sessionInfo.want == nullptr) {
12660         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo.want is nullptr, init");
12661         sessionInfo.want = std::make_shared<AAFwk::Want>();
12662         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
12663             sessionInfo.moduleName_);
12664     }
12665     auto accessTokenIDEx = sessionInfo.callingTokenId_;
12666     if (collaborator != nullptr) {
12667         containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
12668             std::chrono::system_clock::now().time_since_epoch()).count();
12669 
12670         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
12671         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
12672             TLOGI(WmsLogTag::WMS_LIFE, "want affinity exit %{public}s.", affinity.c_str());
12673             return BrokerStates::BROKER_UNKOWN;
12674         }
12675         sessionInfo.want->SetParam("oh_persistentId", persistentId);
12676         std::shared_ptr<int32_t> ret = std::make_shared<int32_t>(0);
12677         std::shared_ptr<AAFwk::Want> notifyWant = std::make_shared<AAFwk::Want>(sessionInfo.GetWantSafely());
12678         bool isTimeout = ffrtQueueHelper_->SubmitTaskAndWait([this, collaborator, accessTokenIDEx,
12679             notifyWant, abilityInfo = sessionInfo.abilityInfo, windowMode = sessionInfo.windowMode, ret] {
12680             int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("WMS:SSM:NotifyStartAbility",
12681                 NOTIFY_START_ABILITY_TIMEOUT/1000, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
12682             auto result = collaborator->NotifyStartAbility(*abilityInfo, currentUserId_, *notifyWant,
12683                 static_cast<uint64_t>(accessTokenIDEx), windowMode);
12684             HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
12685             *ret = static_cast<int32_t>(result);
12686         }, NOTIFY_START_ABILITY_TIMEOUT);
12687 
12688         if (isTimeout) {
12689             TLOGE(WmsLogTag::WMS_LIFE, "notify start ability timeout, id: %{public}d", persistentId);
12690             return BrokerStates::BROKER_NOT_START;
12691         }
12692         sessionInfo.SetWantSafely(*notifyWant);
12693         TLOGI(WmsLogTag::WMS_LIFE, "collaborator ret: %{public}d", *ret);
12694         if (*ret == 0) {
12695             return BrokerStates::BROKER_STARTED;
12696         } else {
12697             return BrokerStates::BROKER_NOT_START;
12698         }
12699     }
12700     return BrokerStates::BROKER_UNKOWN;
12701 }
12702 
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)12703 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
12704 {
12705     if (sceneSession == nullptr) {
12706         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
12707         return;
12708     }
12709     if (sessionInfo.want == nullptr) {
12710         TLOGI(WmsLogTag::DEFAULT, "sessionInfo.want is nullptr");
12711         return;
12712     }
12713     if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
12714         auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
12715         abilitySessionInfo->want = sessionInfo.GetWantSafely();
12716         int32_t missionId = abilitySessionInfo->persistentId;
12717         std::string bundleName = sessionInfo.bundleName_;
12718         int64_t timestamp = containerStartAbilityTime_;
12719         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
12720         TLOGI(WmsLogTag::DEFAULT, "call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
12721             missionId, bundleName.c_str());
12722         collaborator->NotifyMissionCreated(abilitySessionInfo);
12723     }
12724 }
12725 
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)12726 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
12727     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
12728 {
12729     TLOGD(WmsLogTag::DEFAULT, "type: %{public}d", collaboratorType);
12730     if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
12731         TLOGI(WmsLogTag::DEFAULT, "called");
12732         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
12733     }
12734 }
12735 
12736 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)12737 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
12738 {
12739     TLOGD(WmsLogTag::DEFAULT, "in");
12740     if (sceneSession == nullptr) {
12741         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
12742         return;
12743     }
12744     if (auto collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType())) {
12745         TLOGI(WmsLogTag::DEFAULT, "called UpdateMissionInfo");
12746         auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
12747         collaborator->UpdateMissionInfo(abilitySessionInfo);
12748     }
12749 }
12750 
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)12751 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
12752 {
12753     TLOGD(WmsLogTag::DEFAULT, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
12754     if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
12755         TLOGI(WmsLogTag::DEFAULT, "called %{public}d", persistentId);
12756         collaborator->NotifyMoveMissionToForeground(persistentId);
12757     }
12758 }
12759 
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)12760 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
12761 {
12762     TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, type: %{public}d", persistentId, collaboratorType);
12763     if (auto collaborator = GetCollaboratorByType(collaboratorType)) {
12764         const char* const where = __func__;
12765         ffrtQueueHelper_->SubmitTask([collaborator, persistentId, where] {
12766             int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("WMS:SSM:NotifyClearMission",
12767                 NOTIFY_START_ABILITY_TIMEOUT/1000, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
12768             int32_t ret = collaborator->NotifyClearMission(persistentId);
12769             HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
12770             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s called clear mission ret: %{public}d, persistent id: %{public}d",
12771                 where, ret, persistentId);
12772         });
12773     }
12774 }
12775 
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)12776 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
12777 {
12778     if (sceneSession == nullptr) {
12779         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
12780         return false;
12781     }
12782     std::string sessionAffinity;
12783     TLOGI(WmsLogTag::WMS_LIFE, "call");
12784     if (sceneSession->GetSessionInfo().want != nullptr) {
12785         sessionAffinity = sceneSession->GetSessionInfo().want
12786             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
12787     }
12788     if (sessionAffinity.empty()) {
12789         TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
12790         BrokerStates notifyReturn = NotifyStartAbility(
12791             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
12792         if (notifyReturn == BrokerStates::BROKER_NOT_START) {
12793             TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
12794             return false;
12795         }
12796     }
12797     if (sceneSession->GetSessionInfo().want != nullptr) {
12798         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
12799             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
12800         TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
12801             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
12802             sceneSession->GetSessionInfo().sessionAffinity.c_str());
12803     } else {
12804         TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
12805     }
12806     return true;
12807 }
12808 
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)12809 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
12810 {
12811     if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
12812         return false;
12813     }
12814     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
12815     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
12816     return true;
12817 }
12818 
AddWindowDragHotArea(DisplayId displayId,uint32_t type,WSRect & area)12819 void SceneSessionManager::AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)
12820 {
12821     TLOGI(WmsLogTag::WMS_LAYOUT, "displayId: %{public}" PRIu64 ", "
12822         "type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
12823         "height: %{public}d", displayId, type, area.posX_, area.posY_, area.width_, area.height_);
12824     SceneSession::AddOrUpdateWindowDragHotArea(displayId, type, area);
12825 }
12826 
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)12827 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
12828 {
12829     auto task = [this, persistentId, isMaximize]() {
12830         TLOGND(WmsLogTag::WMS_PC, "update maximize mode, id: %{public}d, isMaximize: %{public}d",
12831             persistentId, isMaximize);
12832         auto sceneSession = GetSceneSession(persistentId);
12833         if (sceneSession == nullptr) {
12834             TLOGNE(WmsLogTag::WMS_PC, "could not find window, persistentId:%{public}d", persistentId);
12835             return WSError::WS_ERROR_INVALID_WINDOW;
12836         }
12837         sceneSession->UpdateMaximizeMode(isMaximize);
12838         return WSError::WS_OK;
12839     };
12840     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
12841     return WSError::WS_OK;
12842 }
12843 
GetIsLayoutFullScreen(bool & isLayoutFullScreen)12844 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
12845 {
12846     auto task = [this, &isLayoutFullScreen]() {
12847         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12848         for (const auto& [_, sceneSession] : sceneSessionMap_) {
12849             if (sceneSession == nullptr) {
12850                 TLOGNE(WmsLogTag::WMS_IMMS, "Session is nullptr");
12851                 continue;
12852             }
12853             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12854                 continue;
12855             }
12856             auto state = sceneSession->GetSessionState();
12857             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
12858                 continue;
12859             }
12860             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
12861                 continue;
12862             }
12863             isLayoutFullScreen = sceneSession->GetSessionProperty()->IsLayoutFullScreen();
12864             if (isLayoutFullScreen) {
12865                 TLOGND(WmsLogTag::WMS_IMMS, "Current window is immersive, persistentId:%{public}d",
12866                     sceneSession->GetPersistentId());
12867                 return WSError::WS_OK;
12868             } else {
12869                 TLOGND(WmsLogTag::WMS_IMMS, "Current window is not immersive, persistentId:%{public}d",
12870                     sceneSession->GetPersistentId());
12871             }
12872         }
12873         TLOGND(WmsLogTag::WMS_IMMS, "No immersive window");
12874         return WSError::WS_OK;
12875     };
12876 
12877     taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
12878     return WSError::WS_OK;
12879 }
12880 
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)12881 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
12882 {
12883     auto sceneSession = GetSceneSession(persistentId);
12884     if (!sceneSession) {
12885         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
12886         return WSError::WS_ERROR_INVALID_WINDOW;
12887     }
12888     auto fromScreenId = sceneSession->GetSessionInfo().screenId_;
12889     sceneSession->SetScreenId(screenId);
12890     sceneSession->GetSessionProperty()->SetDisplayId(screenId);
12891     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, move display %{public}" PRIu64 " from %{public}" PRIu64,
12892         sceneSession->GetPersistentId(), screenId, fromScreenId);
12893     NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
12894     sceneSession->NotifyDisplayMove(fromScreenId, screenId);
12895     sceneSession->UpdateDensity();
12896     if (fromScreenId != screenId) {
12897         sceneSession->AddPropertyDirtyFlags(static_cast<uint32_t>(SessionPropertyFlag::DISPLAY_ID));
12898     }
12899     uint64_t displayId = screenId;
12900     if (sceneSession->IsPcFoldDevice() && PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
12901         displayId = sceneSession->GetClientDisplayId();
12902     }
12903     NotifyDisplayIdChanged(persistentId, displayId);
12904     return WSError::WS_OK;
12905 }
12906 
NotifyStackEmpty(int32_t persistentId)12907 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
12908 {
12909     TLOGI(WmsLogTag::WMS_LIFE, "persistentId %{public}d", persistentId);
12910     auto task = [this, persistentId]() {
12911         auto sceneSession = GetSceneSession(persistentId);
12912         if (!sceneSession) {
12913             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
12914             return WSError::WS_ERROR_INVALID_WINDOW;
12915         }
12916         NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::STACK_EMPTY);
12917         return WSError::WS_OK;
12918     };
12919     taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
12920     return WSError::WS_OK;
12921 }
12922 
OnImmersiveStateChange(ScreenId screenId,bool & immersive)12923 void DisplayChangeListener::OnImmersiveStateChange(ScreenId screenId, bool& immersive)
12924 {
12925     immersive = SceneSessionManager::GetInstance().GetImmersiveState(screenId);
12926 }
12927 
GetImmersiveState(ScreenId screenId)12928 bool SceneSessionManager::GetImmersiveState(ScreenId screenId)
12929 {
12930     return taskScheduler_->PostSyncTask([this, screenId, where = __func__] {
12931         bool isPcOrPadFreeMultiWindowMode = false;
12932         IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
12933         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12934         for (const auto& [_, sceneSession] : sceneSessionMap_) {
12935             if (sceneSession == nullptr) {
12936                 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
12937                 continue;
12938             }
12939             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
12940                 continue;
12941             }
12942             auto state = sceneSession->GetSessionState();
12943             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
12944                 continue;
12945             }
12946             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
12947                 continue;
12948             }
12949             if (sceneSession->GetSessionProperty()->GetDisplayId() != screenId) {
12950                 continue;
12951             }
12952             if (isPcOrPadFreeMultiWindowMode) {
12953                 if (sceneSession->IsLayoutFullScreen()) {
12954                     return true;
12955                 }
12956                 continue;
12957             }
12958             auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
12959             if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
12960                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
12961                     sceneSession->GetPersistentId());
12962                 return true;
12963             } else {
12964                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
12965                     sceneSession->GetPersistentId());
12966                 break;
12967             }
12968         }
12969         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
12970         return false;
12971     }, __func__);
12972 }
12973 
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)12974 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
12975     bool withAnimation)
12976 {
12977     session->NotifySessionForeground(reason, withAnimation);
12978 }
12979 
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)12980 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
12981     bool withAnimation, bool isFromInnerkits)
12982 {
12983     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
12984 }
12985 
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)12986 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
12987 {
12988     auto sceneSession = GetSceneSession(persistentId);
12989     if (sceneSession == nullptr) {
12990         TLOGE(WmsLogTag::DEFAULT, "could not find window, persistentId:%{public}d", persistentId);
12991         return WSError::WS_ERROR_INVALID_WINDOW;
12992     }
12993     return sceneSession->UpdateTitleInTargetPos(isShow, height);
12994 }
12995 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)12996 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
12997 {
12998     TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted");
12999     if (debugInfos.empty()) {
13000         TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStarted debugInfos is empty");
13001         return;
13002     }
13003 }
13004 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)13005 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
13006 {
13007     TLOGI(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped");
13008     if (debugInfos.empty()) {
13009         TLOGE(WmsLogTag::DEFAULT, "AppAnrListener OnAppDebugStoped debugInfos is empty");
13010         return;
13011     }
13012 }
13013 
SetHasRootSceneRequestedVsyncFunc(HasRootSceneRequestedVsyncFunc && func)13014 void SceneSessionManager::SetHasRootSceneRequestedVsyncFunc(HasRootSceneRequestedVsyncFunc&& func)
13015 {
13016     if (!func) {
13017         TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13018         return;
13019     }
13020     hasRootSceneRequestedVsyncFunc_ = std::move(func);
13021 }
13022 
HasRootSceneRequestedVsync(bool & hasRootSceneRequestedVsync)13023 WSError SceneSessionManager::HasRootSceneRequestedVsync(bool& hasRootSceneRequestedVsync)
13024 {
13025     if (!hasRootSceneRequestedVsyncFunc_) {
13026         TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13027         return WSError::WS_ERROR_NULLPTR;
13028     }
13029     hasRootSceneRequestedVsync = hasRootSceneRequestedVsyncFunc_();
13030     return WSError::WS_OK;
13031 }
13032 
SetRequestVsyncByRootSceneWhenModeChangeFunc(RequestVsyncByRootSceneWhenModeChangeFunc && func)13033 void SceneSessionManager::SetRequestVsyncByRootSceneWhenModeChangeFunc(
13034     RequestVsyncByRootSceneWhenModeChangeFunc&& func)
13035 {
13036     if (!func) {
13037         TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13038         return;
13039     }
13040     requestVsyncByRootSceneWhenModeChangeFunc_ = std::move(func);
13041 }
13042 
UpdateWindowModeByIdForUITest(int32_t windowId,int32_t updateMode)13043 WMError SceneSessionManager::UpdateWindowModeByIdForUITest(int32_t windowId, int32_t updateMode)
13044 {
13045     if (!SessionPermission::IsSACalling()) {
13046         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
13047         return WMError::WM_ERROR_INVALID_PERMISSION;
13048     }
13049     auto task = [this, windowId, updateMode, where = __func__] {
13050         auto sceneSession = GetSceneSession(windowId);
13051         if (sceneSession == nullptr) {
13052             TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr, windowId: %{public}d, updateMode: %{public}d",
13053                 windowId, updateMode);
13054             return WMError::WM_ERROR_INVALID_WINDOW;
13055         }
13056         TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s, windowId: %{public}d, updateMode: %{public}d", where , windowId, updateMode);
13057         return sceneSession->UpdateWindowModeForUITest(updateMode);
13058     };
13059     return taskScheduler_->PostSyncTask(task,
13060         "UpdateWindowModeByIdForUITest windowId: " + std::to_string(windowId) + " updateMode: " + std::to_string(updateMode));
13061 }
13062 
RequestVsyncByRootSceneWhenModeChange(const std::shared_ptr<VsyncCallback> & vsyncCallback)13063 WSError SceneSessionManager::RequestVsyncByRootSceneWhenModeChange(const std::shared_ptr<VsyncCallback>& vsyncCallback)
13064 {
13065     if (!requestVsyncByRootSceneWhenModeChangeFunc_) {
13066         TLOGW(WmsLogTag::WMS_LAYOUT, "func is null");
13067         return WSError::WS_ERROR_NULLPTR;
13068     }
13069     requestVsyncByRootSceneWhenModeChangeFunc_(vsyncCallback);
13070     return WSError::WS_OK;
13071 }
13072 
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)13073 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
13074 {
13075     if (!Session::IsScbCoreEnabled()) {
13076         return;
13077     }
13078     if (onFlushUIParamsFunc_ != nullptr) {
13079         onFlushUIParamsFunc_();
13080     }
13081     const char* const where = __func__;
13082     taskScheduler_->PostAsyncTask([this, screenId, where,
13083         uiParams = std::move(uiParams)]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
13084         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
13085         TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s", where);
13086         {
13087             std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
13088             nextFlushCompletedCV_.notify_all();
13089         }
13090         std::vector<std::pair<uint32_t, uint32_t>> appZOrderList;
13091         processingFlushUIParams_.store(true);
13092         auto keyboardSession = GetKeyboardSession(screenId, false);
13093         {
13094             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13095             for (const auto& [_, sceneSession] : sceneSessionMap_) {
13096                 if (sceneSession == nullptr) {
13097                     continue;
13098                 }
13099                 if (isNotCurrentScreen(sceneSession, screenId)) {
13100                     TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s The screenId of this Scenesession is invalid", where);
13101                     continue;
13102                 }
13103                 if (auto iter = uiParams.find(sceneSession->GetPersistentId()); iter != uiParams.end()) {
13104                     if ((systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow()) &&
13105                         sceneSession->IsAppSession()) {
13106                         if (!sceneSession->IsVisible()) {
13107                             appZOrderList.push_back(std::make_pair(0, iter->second.zOrder_));
13108                         }
13109                         appZOrderList.push_back(std::make_pair(sceneSession->GetZOrder(), iter->second.zOrder_));
13110                     }
13111                     sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
13112                 } else {
13113                     sessionMapDirty_ |= sceneSession->UpdateUIParam();
13114                 }
13115             }
13116             if (keyboardSession != nullptr) {
13117                 keyboardSession->CalculateOccupiedAreaAfterUIRefresh();
13118             }
13119         }
13120         processingFlushUIParams_.store(false);
13121 
13122         // post process if dirty
13123         if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
13124             static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
13125             TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s found dirty: %{public}d", where, sessionMapDirty_);
13126             for (const auto& item : uiParams) {
13127                 TLOGND(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f,"
13128                     " transY:%{public}f, needSync:%{public}d, interactive:%{public}d", item.first, item.second.zOrder_,
13129                     item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
13130                     item.second.needSync_, item.second.interactive_);
13131             }
13132             ProcessUpdateLastFocusedAppId(appZOrderList);
13133             ProcessFocusZOrderChange(sessionMapDirty_);
13134             PostProcessFocus();
13135             PostProcessProperty(sessionMapDirty_);
13136             NotifyAllAccessibilityInfo();
13137             AnomalyDetection::SceneZOrderCheckProcess();
13138         } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
13139             PostProcessProperty(sessionMapDirty_);
13140         }
13141         FlushWindowInfoToMMI();
13142         NotifyWindowPropertyChange(screenId);
13143         sessionMapDirty_ = 0;
13144         {
13145             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13146             for (const auto& [_, sceneSession] : sceneSessionMap_) {
13147                 if (sceneSession == nullptr) {
13148                     continue;
13149                 }
13150                 if (isNotCurrentScreen(sceneSession, screenId)) {
13151                     TLOGND(WmsLogTag::WMS_PIPELINE, "%{public}s The screenId of this Scenesession is invalid", where);
13152                     continue;
13153                 }
13154                 sceneSession->ResetSizeChangeReasonIfDirty();
13155                 sceneSession->ResetDirtyFlags();
13156                 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
13157                     sceneSession->SetUIStateDirty(false);
13158                 }
13159             }
13160         }
13161         if (needCloseSync_) {
13162             if (closeSyncFunc_) {
13163                 closeSyncFunc_();
13164             }
13165             needCloseSync_ = false;
13166         }
13167     }, __func__);
13168 }
13169 
ProcessUpdateLastFocusedAppId(const std::vector<std::pair<uint32_t,uint32_t>> & zOrderList)13170 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<std::pair<uint32_t, uint32_t>>& zOrderList)
13171 {
13172     auto focusGroup = windowFocusController_->GetFocusGroup(DEFAULT_DISPLAY_ID);
13173     if (focusGroup == nullptr) {
13174         TLOGE(WmsLogTag::WMS_FOCUS, "focus group is nullptr: %{public}" PRIu64, DEFAULT_DISPLAY_ID);
13175         return;
13176     }
13177     auto lastFocusedAppSessionId = focusGroup->GetLastFocusedAppSessionId();
13178     TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu",
13179         lastFocusedAppSessionId, zOrderList.size());
13180     if (lastFocusedAppSessionId == INVALID_SESSION_ID || zOrderList.empty()) {
13181         return;
13182     }
13183     auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId);
13184     if (lastFocusedAppSession == nullptr) {
13185         return;
13186     }
13187     uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
13188     auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder]
13189         (const std::pair<uint32_t, uint32_t>& pair) {
13190         return pair.first < lastFocusedAppZOrder && pair.second > lastFocusedAppZOrder;
13191     });
13192     if (it != zOrderList.end()) {
13193         TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
13194         focusGroup->SetLastFocusedAppSessionId(INVALID_SESSION_ID);
13195     }
13196 }
13197 
ProcessFocusZOrderChange(uint32_t dirty)13198 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
13199 {
13200     if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
13201         return;
13202     }
13203     if (!systemConfig_.IsPhoneWindow() && !systemConfig_.IsPadWindow()) {
13204         return;
13205     }
13206     TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
13207     auto focusedSessionId = GetFocusedSessionId(DEFAULT_DISPLAY_ID);
13208     auto focusedSession = GetSceneSession(focusedSessionId);
13209     // only when it's from a high zOrder to a low zOrder
13210     if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
13211         focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
13212         return;
13213     }
13214     auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
13215     if (voiceInteractionSession == nullptr) {
13216         return;
13217     }
13218     TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
13219           "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
13220           voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
13221     if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
13222         focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
13223         return;
13224     }
13225     RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
13226 }
13227 
PostProcessFocus()13228 void SceneSessionManager::PostProcessFocus()
13229 {
13230     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
13231     // priority process focus requests from top to bottom
13232     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
13233     {
13234         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13235         for (auto& iter : sceneSessionMap_) {
13236             auto session = iter.second;
13237             if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
13238                 continue;
13239             }
13240             processingSessions.push_back(iter);
13241         }
13242     }
13243     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
13244         bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
13245             !rhs.second->GetPostProcessFocusState().isFocused_;
13246         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
13247         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
13248         return focusCmp || lhsZOrder > rhsZOrder;
13249     };
13250     std::sort(processingSessions.begin(), processingSessions.end(), cmp);
13251 
13252     // only change focus one time
13253     std::unordered_set<DisplayId> focusChangedSet;
13254     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
13255         auto session = iter->second;
13256         if (session == nullptr) {
13257             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
13258             continue;
13259         }
13260         auto displayId = session->GetSessionProperty()->GetDisplayId();
13261         auto displayGroupId = windowFocusController_->GetDisplayGroupId(displayId);
13262         TLOGD(WmsLogTag::WMS_PIPELINE,
13263             "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
13264             session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
13265             session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
13266         if (focusChangedSet.find(displayGroupId) != focusChangedSet.end()) {
13267             session->ResetPostProcessFocusState();
13268             continue;
13269         }
13270         if (!session->IsFocusedOnShow()) {
13271             if (IsSessionVisibleForeground(session)) {
13272                 session->SetFocusedOnShow(true);
13273             }
13274             session->ResetPostProcessFocusState();
13275             continue;
13276         }
13277 
13278         WSError ret = WSError::WS_DO_NOTHING;
13279         if (session->GetPostProcessFocusState().isFocused_) {
13280             if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP &&
13281                 session->IsDelayFocusChange()) {
13282                 TLOGI(WmsLogTag::WMS_FOCUS, "delay focus change until the window is visible");
13283                 continue;
13284             } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
13285                 ret = RequestSessionFocusImmediately(session->GetPersistentId());
13286             } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::RECENT) {
13287                 ret = RequestSessionFocus(session->GetPersistentId(),
13288                                           session->GetPostProcessFocusState().byForeground_,
13289                                           session->GetPostProcessFocusState().reason_);
13290             } else {
13291                 ret = RequestSessionFocus(session->GetPersistentId(), true,
13292                                           session->GetPostProcessFocusState().reason_);
13293             }
13294         } else {
13295             ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
13296         }
13297         session->ResetPostProcessFocusState();
13298         // if succeed then end process
13299         if (ret == WSError::WS_OK) {
13300             focusChangedSet.insert(displayGroupId);
13301         }
13302     }
13303 }
13304 
PostProcessProperty(uint32_t dirty)13305 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
13306 {
13307     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
13308     if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
13309         // only trigger update avoid area
13310         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13311         for (auto& iter : sceneSessionMap_) {
13312             auto session = iter.second;
13313             if (session == nullptr) {
13314                 continue;
13315             }
13316             session->PostProcessNotifyAvoidArea();
13317         }
13318         return;
13319     }
13320 
13321     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
13322     {
13323         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13324         for (auto& iter : sceneSessionMap_) {
13325             auto session = iter.second;
13326             if (session == nullptr || !session->GetPostProcessProperty()) {
13327                 continue;
13328             }
13329             processingSessions.push_back(iter);
13330         }
13331     }
13332 
13333     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
13334         auto session = iter->second;
13335         if (session == nullptr) {
13336             TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
13337             continue;
13338         }
13339         TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
13340         UpdateForceHideState(session, session->GetSessionProperty(), true);
13341         HandleKeepScreenOn(session, session->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX, session->keepScreenLock_);
13342         HandleKeepScreenOn(session, session->IsViewKeepScreenOn(), VIEW_SCREEN_LOCK_PREFIX,
13343                            session->viewKeepScreenLock_);
13344         UpdatePrivateStateAndNotify(session->GetPersistentId());
13345         if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
13346             ProcessSubSessionForeground(session);
13347         }
13348         session->SetPostProcessProperty(false);
13349     }
13350 
13351     // update avoid area
13352     {
13353         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13354         for (auto& iter : sceneSessionMap_) {
13355             auto session = iter.second;
13356             if (session == nullptr) {
13357                 continue;
13358             }
13359             session->PostProcessNotifyAvoidArea();
13360         }
13361     }
13362 }
13363 
13364 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)13365 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
13366 {
13367     TLOGI(WmsLogTag::WMS_HIERARCHY, "id %{public}d", persistentId);
13368     auto isSaCall = SessionPermission::IsSACalling();
13369     if (!isSaCall) {
13370         TLOGE(WmsLogTag::WMS_HIERARCHY, "The interface only support for sa call");
13371         return WSError::WS_ERROR_INVALID_PERMISSION;
13372     }
13373     auto task = [this, persistentId]() {
13374         auto sceneSession = GetSceneSession(persistentId);
13375         if (sceneSession == nullptr) {
13376             TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is nullptr");
13377             return WSError::WS_ERROR_INVALID_SESSION;
13378         }
13379         if (!IsSessionVisibleForeground(sceneSession)) {
13380             TLOGND(WmsLogTag::WMS_HIERARCHY, "session is not visible!");
13381             return WSError::WS_DO_NOTHING;
13382         }
13383         FocusChangeReason reason = FocusChangeReason::MOVE_UP;
13384         RequestSessionFocus(persistentId, true, reason);
13385         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
13386             sceneSession->RaiseToAppTop();
13387         }
13388         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
13389             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
13390             TLOGND(WmsLogTag::WMS_HIERARCHY, "parent session id: %{public}d", sceneSession->GetParentPersistentId());
13391             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
13392         }
13393         if (sceneSession == nullptr) {
13394             TLOGNE(WmsLogTag::WMS_HIERARCHY, "parent session is nullptr");
13395             return WSError::WS_ERROR_INVALID_SESSION;
13396         }
13397         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
13398             sceneSession->NotifyClick(true, false);
13399             return WSError::WS_OK;
13400         } else {
13401             TLOGNE(WmsLogTag::WMS_HIERARCHY, "session is not app main window!");
13402             return WSError::WS_ERROR_INVALID_SESSION;
13403         }
13404     };
13405     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
13406     return WSError::WS_OK;
13407 }
13408 
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)13409 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
13410 {
13411     TLOGI(WmsLogTag::WMS_FOCUS, "from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
13412     sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
13413     if (sourceSession == nullptr) {
13414         TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr, id: %{public}d", sourcePersistentId);
13415         return WSError::WS_ERROR_INVALID_SESSION;
13416     }
13417     auto displayId = sourceSession->GetSessionProperty()->GetDisplayId();
13418     auto focusedSessionId = GetFocusedSessionId(displayId);
13419     if (sourcePersistentId != focusedSessionId) {
13420         TLOGE(WmsLogTag::WMS_FOCUS, "source session need be focused, focusedSessionId: %{public}d", focusedSessionId);
13421         return WSError::WS_ERROR_INVALID_OPERATION;
13422     }
13423     if (targetPersistentId == focusedSessionId) {
13424         TLOGE(WmsLogTag::WMS_FOCUS, "target session has been focused, focusedSessionId: %{public}d", focusedSessionId);
13425         return WSError::WS_DO_NOTHING;
13426     }
13427     WSError ret = GetAppMainSceneSession(sourcePersistentId, sourceSession);
13428     if (ret != WSError::WS_OK) {
13429         return ret;
13430     }
13431     sptr<SceneSession> targetSession = nullptr;
13432     ret = GetAppMainSceneSession(targetPersistentId, targetSession);
13433     if (ret != WSError::WS_OK) {
13434         return ret;
13435     }
13436     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
13437         TLOGE(WmsLogTag::WMS_FOCUS, "verify bundle failed, source name is %{public}s but target name is %{public}s)",
13438             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
13439         return WSError::WS_ERROR_INVALID_CALLING;
13440     }
13441     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
13442         return WSError::WS_ERROR_INVALID_CALLING;
13443     }
13444     int32_t callingPid = IPCSkeleton::GetCallingPid();
13445     if (callingPid != targetSession->GetCallingPid()) {
13446         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
13447         return WSError::WS_ERROR_INVALID_CALLING;
13448     }
13449     targetSession->NotifyClick(true, false);
13450     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
13451     return RequestSessionFocus(targetPersistentId, false, reason);
13452 }
13453 
GetAppMainSceneSession(int32_t persistentId,sptr<SceneSession> & sceneSession)13454 WSError SceneSessionManager::GetAppMainSceneSession(int32_t persistentId, sptr<SceneSession>& sceneSession)
13455 {
13456     sceneSession = GetSceneSession(persistentId);
13457     if (sceneSession == nullptr) {
13458         TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is nullptr", persistentId);
13459         return WSError::WS_ERROR_INVALID_SESSION;
13460     }
13461     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
13462         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
13463             TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) is not main window or sub window", persistentId);
13464             return WSError::WS_ERROR_INVALID_CALLING;
13465         }
13466         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
13467         if (sceneSession == nullptr) {
13468             TLOGE(WmsLogTag::DEFAULT, "session(%{public}d) parent is nullptr", persistentId);
13469             return WSError::WS_ERROR_INVALID_SESSION;
13470         }
13471     }
13472     return WSError::WS_OK;
13473 }
13474 
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam,SnapshotNodeType snapshotNode,bool needSnapshot)13475 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
13476     const float scaleParam, SnapshotNodeType snapshotNode, bool needSnapshot)
13477 {
13478     auto sceneSession = GetSceneSession(persistentId);
13479     if (!sceneSession) {
13480         TLOGE(WmsLogTag::WMS_MAIN, "get scene session is nullptr");
13481         return nullptr;
13482     }
13483 
13484     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
13485     auto isPersistentImageFit = ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(persistentId),
13486         ScenePersistentStorageType::MAXIMIZE_STATE);
13487 
13488     bool isPc = systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode();
13489     bool useCurWindow = (snapshotNode == SnapshotNodeType::DEFAULT_NODE) ?
13490         isPc : (snapshotNode == SnapshotNodeType::LEASH_NODE) ? false : true;
13491     std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
13492     if (needSnapshot && !isPersistentImageFit) {
13493         pixelMap = sceneSession->Snapshot(true, scaleParam, useCurWindow);
13494     }
13495     if (!pixelMap) {
13496         TLOGI(WmsLogTag::WMS_MAIN, "get local snapshot pixelmap start");
13497         pixelMap = sceneSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
13498     }
13499     return pixelMap;
13500 }
13501 
GetSceneSessionMap()13502 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
13503 {
13504     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
13505     {
13506         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13507         retSceneSessionMap = sceneSessionMap_;
13508     }
13509     EraseIf(retSceneSessionMap, [this](const auto& pair) {
13510         if (pair.second == nullptr) {
13511             return true;
13512         }
13513 
13514         if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
13515             if (pair.second->IsVisible()) {
13516                 return false;
13517             }
13518             return true;
13519         }
13520 
13521         if (pair.second->IsSystemInput()) {
13522             return false;
13523         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
13524             return false;
13525         }
13526 
13527         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
13528             return true;
13529         }
13530         return false;
13531     });
13532     return retSceneSessionMap;
13533 }
13534 
NotifyUpdateRectAfterLayout()13535 void SceneSessionManager::NotifyUpdateRectAfterLayout()
13536 {
13537     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
13538     std::shared_ptr<RSUIContext> rsUIContext;
13539     if (auto rootSceneSession = GetRootSceneSession()) {
13540         rsUIContext = rootSceneSession->GetRSUIContext();
13541     }
13542     rsTransaction = RSSyncTransactionAdapter::GetRSTransaction(rsUIContext);
13543     auto task = [this, rsTransaction] {
13544         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13545         for (const auto& [_, sceneSession] : sceneSessionMap_) {
13546             if (sceneSession && sceneSession->IsDirtyWindow()) {
13547                 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
13548             }
13549         }
13550     };
13551     // need sync task since animation transcation need
13552     taskScheduler_->PostAsyncTask(task, __func__);
13553 }
13554 
ListWindowInfo(const WindowInfoOption & windowInfoOption,std::vector<sptr<WindowInfo>> & infos)13555 WMError SceneSessionManager::ListWindowInfo(const WindowInfoOption& windowInfoOption,
13556     std::vector<sptr<WindowInfo>>& infos)
13557 {
13558     if (!(SessionPermission::IsSACalling())) {
13559         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied");
13560         return WMError::WM_ERROR_INVALID_PERMISSION;
13561     }
13562     const char* const where = __func__;
13563     return taskScheduler_->PostSyncTask([this, windowInfoOption, &infos, where] {
13564         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::ListWindowInfo (%u) "
13565             "(%u) (%" PRIu64 ") (%d)",
13566             static_cast<WindowInfoFilterOptionDataType>(windowInfoOption.windowInfoFilterOption),
13567             static_cast<WindowInfoTypeOptionDataType>(windowInfoOption.windowInfoTypeOption),
13568             windowInfoOption.displayId, windowInfoOption.windowId);
13569         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13570         for (const auto& [_, sceneSession] : sceneSessionMap_) {
13571             if (sceneSession == nullptr) {
13572                 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: session is null", where);
13573                 continue;
13574             }
13575             if (!FilterForListWindowInfo(windowInfoOption, sceneSession)) {
13576                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: filter win: %{public}d",
13577                     where, sceneSession->GetWindowId());
13578                 continue;
13579             }
13580             auto windowInfo = sptr<WindowInfo>::MakeSptr();
13581             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_UI_INFO)) {
13582                 windowInfo->windowUIInfo = sceneSession->GetWindowUIInfoForWindowInfo();
13583             }
13584             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_DISPLAY_INFO)) {
13585                 windowInfo->windowDisplayInfo = sceneSession->GetWindowDisplayInfoForWindowInfo();
13586             }
13587             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_LAYOUT_INFO)) {
13588                 windowInfo->windowLayoutInfo = sceneSession->GetWindowLayoutInfoForWindowInfo();
13589             }
13590             if (IsChosenWindowOption(windowInfoOption.windowInfoTypeOption, WindowInfoTypeOption::WINDOW_META_INFO)) {
13591                 windowInfo->windowMetaInfo = sceneSession->GetWindowMetaInfoForWindowInfo();
13592             }
13593             infos.emplace_back(windowInfo);
13594         }
13595         return WMError::WM_OK;
13596     }, __func__);
13597 }
13598 
FilterForListWindowInfo(const WindowInfoOption & windowInfoOption,const sptr<SceneSession> & sceneSession) const13599 bool SceneSessionManager::FilterForListWindowInfo(const WindowInfoOption& windowInfoOption,
13600     const sptr<SceneSession>& sceneSession) const
13601 {
13602     DisplayId displayId = windowInfoOption.displayId;
13603     if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(sceneSession->GetSessionProperty()->GetDisplayId())) {
13604         if (displayId == DEFAULT_DISPLAY_ID && sceneSession->GetSessionGlobalRect().posY_ >= GetFoldLowerScreenPosY()) {
13605             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "fold lower screen win: %{public}d", sceneSession->GetWindowId());
13606             return false;
13607         }
13608         if (displayId == VIRTUAL_DISPLAY_ID) {
13609             if (sceneSession->GetSessionGlobalRect().posY_ +
13610                 sceneSession->GetSessionGlobalRect().height_ < GetFoldLowerScreenPosY()) {
13611                 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "fold virtual screen win: %{public}d", sceneSession->GetWindowId());
13612                 return false;
13613             }
13614             displayId = DEFAULT_DISPLAY_ID;
13615         }
13616     }
13617     if (displayId != DISPLAY_ID_INVALID && sceneSession->GetSessionProperty()->GetDisplayId() != displayId) {
13618         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "win: %{public}d, target displayId: %{public}" PRIu64,
13619             sceneSession->GetWindowId(), displayId);
13620         return false;
13621     }
13622     if (windowInfoOption.windowId != 0 && sceneSession->GetWindowId() != windowInfoOption.windowId) {
13623         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "win: %{public}d, target winId: %{public}d",
13624             sceneSession->GetWindowId(), windowInfoOption.windowId);
13625         return false;
13626     }
13627     if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::EXCLUDE_SYSTEM) &&
13628         sceneSession->GetSessionInfo().isSystem_) {
13629         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "exclude system win: %{public}d", sceneSession->GetWindowId());
13630         return false;
13631     }
13632     if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::VISIBLE) &&
13633         (sceneSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION ||
13634         sceneSession->GetVisibilityState() == WINDOW_LAYER_STATE_MAX)) {
13635         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "exclude unvisible win: %{public}d", sceneSession->GetWindowId());
13636         return false;
13637     }
13638     if (IsChosenWindowOption(windowInfoOption.windowInfoFilterOption, WindowInfoFilterOption::FOREGROUND) &&
13639         !IsSessionVisibleForeground(sceneSession)) {
13640         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "exclude background win: %{public}d", sceneSession->GetWindowId());
13641         return false;
13642     }
13643     return true;
13644 }
13645 
GetAllWindowLayoutInfo(DisplayId displayId,std::vector<sptr<WindowLayoutInfo>> & infos)13646 WMError SceneSessionManager::GetAllWindowLayoutInfo(DisplayId displayId,
13647     std::vector<sptr<WindowLayoutInfo>>& infos)
13648 {
13649     auto task = [this, displayId, &infos, funcName = __func__]() mutable {
13650         bool isVirtualDisplay = false;
13651         if (displayId == VIRTUAL_DISPLAY_ID) {
13652             displayId = DEFAULT_DISPLAY_ID;
13653             isVirtualDisplay = true;
13654         }
13655         std::vector<sptr<SceneSession>> filteredSessions;
13656         FilterForGetAllWindowLayoutInfo(displayId, isVirtualDisplay, filteredSessions);
13657         for (const auto& session : filteredSessions) {
13658             Rect globalScaledRect;
13659             session->GetGlobalScaledRect(globalScaledRect);
13660             if (isVirtualDisplay) {
13661                 globalScaledRect.posY_ -= GetFoldLowerScreenPosY();
13662             }
13663             HookWindowInfo hookWindowInfo = GetAppHookWindowInfo(session->GetSessionInfo().bundleName_);
13664             if (hookWindowInfo.enableHookWindow &&
13665                 WindowHelper::IsMainWindow(session->GetWindowType()) &&
13666                 !MathHelper::NearEqual(hookWindowInfo.widthHookRatio, HookWindowInfo::DEFAULT_WINDOW_SIZE_HOOK_RATIO)) {
13667                 globalScaledRect.width_ =
13668                     static_cast<uint32_t>(globalScaledRect.width_ * hookWindowInfo.widthHookRatio);
13669                 TLOGD(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}u, hook window width, hooked width:%{public}u, "
13670                     "widthHookRatio:%{public}f.", funcName, session->GetPersistentId(), globalScaledRect.width_,
13671                     hookWindowInfo.widthHookRatio);
13672             }
13673             auto windowLayoutInfo = sptr<WindowLayoutInfo>::MakeSptr();
13674             windowLayoutInfo->rect = globalScaledRect;
13675             infos.emplace_back(windowLayoutInfo);
13676         }
13677         return WMError::WM_OK;
13678     };
13679     return taskScheduler_->PostSyncTask(task, __func__);
13680 }
13681 
FilterForGetAllWindowLayoutInfo(DisplayId displayId,bool isVirtualDisplay,std::vector<sptr<SceneSession>> & filteredSessions)13682 void SceneSessionManager::FilterForGetAllWindowLayoutInfo(DisplayId displayId, bool isVirtualDisplay,
13683     std::vector<sptr<SceneSession>>& filteredSessions)
13684 {
13685     {
13686         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13687         for (const auto& [_, session] : sceneSessionMap_) {
13688             if (session == nullptr) {
13689                 continue;
13690             }
13691             if (session->GetSessionGlobalRect().IsInvalid()) {
13692                 continue;
13693             }
13694             if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(session->GetSessionProperty()->GetDisplayId()) &&
13695                 displayId == DEFAULT_DISPLAY_ID) {
13696                 if (isVirtualDisplay &&
13697                     session->GetSessionRect().posY_ + session->GetSessionRect().height_ < GetFoldLowerScreenPosY()) {
13698                     continue;
13699                 }
13700                 if (!isVirtualDisplay && session->GetSessionRect().posY_ >= GetFoldLowerScreenPosY()) {
13701                     continue;
13702                 }
13703             }
13704             if (IsGetWindowLayoutInfoNeeded(session) && session->GetSessionProperty()->GetDisplayId() == displayId &&
13705                 session->GetVisibilityState() != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
13706                 filteredSessions.emplace_back(session);
13707             }
13708         }
13709     }
13710     std::sort(filteredSessions.begin(), filteredSessions.end(),
13711               [](const sptr<SceneSession>& lhs, const sptr<SceneSession>& rhs) {
13712                   return lhs->GetZOrder() > rhs->GetZOrder();
13713               });
13714 }
13715 
GetFoldLowerScreenPosY() const13716 int32_t SceneSessionManager::GetFoldLowerScreenPosY() const
13717 {
13718     const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
13719         PcFoldScreenManager::GetInstance().GetDisplayRects();
13720     constexpr int32_t SUPER_FOLD_DIVIDE_FACTOR = 2;
13721     return foldCreaseRect.height_ != 0 ?
13722            defaultDisplayRect.height_ - foldCreaseRect.height_ / SUPER_FOLD_DIVIDE_FACTOR + foldCreaseRect.height_ :
13723            defaultDisplayRect.height_;
13724 }
13725 
IsGetWindowLayoutInfoNeeded(const sptr<SceneSession> & session) const13726 bool SceneSessionManager::IsGetWindowLayoutInfoNeeded(const sptr<SceneSession>& session) const
13727 {
13728     std::string name = session->GetWindowName();
13729     size_t pos = name.size();
13730     while (pos > 0 && std::isdigit(static_cast<unsigned char>(name[pos - 1]))) {
13731         --pos;
13732     }
13733     name.resize(pos);
13734     return !session->GetSessionInfo().isSystem_ || LAYOUT_INFO_WHITELIST.find(name) != LAYOUT_INFO_WHITELIST.end();
13735 }
13736 
GetGlobalWindowMode(DisplayId displayId,GlobalWindowMode & globalWinMode)13737 WMError SceneSessionManager::GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode)
13738 {
13739     return taskScheduler_->PostSyncTask([this, displayId, &globalWinMode, where = __func__] {
13740         globalWinMode = GlobalWindowMode::UNKNOWN;
13741         TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: displayId=%{public}" PRIu64, where, displayId);
13742         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13743         for (const auto& [_, session] : sceneSessionMap_) {
13744             if (session == nullptr) {
13745                 TLOGNW(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: session is null", where);
13746                 continue;
13747             }
13748             if (displayId != DISPLAY_ID_INVALID && !IsSessionInSpecificDisplay(session, displayId)) {
13749                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: not in display, win: [%{public}d, %{public}s]",
13750                     where, session->GetWindowId(), session->GetWindowName().c_str());
13751                 continue;
13752             }
13753             if (!session->IsSessionForeground()) {
13754                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: skip win=[%{public}d, %{public}s], stat: %{public}u",
13755                     where, session->GetWindowId(), session->GetWindowName().c_str(),
13756                     static_cast<uint32_t>(session->GetSessionState()));
13757                 continue;
13758             }
13759             WindowMode winMode = session->GetWindowMode();
13760             if (WindowHelper::IsPipWindowMode(winMode)) {
13761                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found pip win=[%{public}d, %{public}s]",
13762                     where, session->GetWindowId(), session->GetWindowName().c_str());
13763                 globalWinMode = globalWinMode | GlobalWindowMode::PIP;
13764             } else if (WindowHelper::IsFullScreenWindow(winMode)) {
13765                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found fullscreen win=[%{public}d, %{public}s]",
13766                     where, session->GetWindowId(), session->GetWindowName().c_str());
13767                 globalWinMode = globalWinMode | GlobalWindowMode::FULLSCREEN;
13768             } else if (WindowHelper::IsSplitWindowMode(winMode)) {
13769                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found split win=[%{public}d, %{public}s]",
13770                     where, session->GetWindowId(), session->GetWindowName().c_str());
13771                 globalWinMode = globalWinMode | GlobalWindowMode::SPLIT;
13772             } else if (WindowHelper::IsFloatingWindow(winMode)) {
13773                 TLOGND(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: found floating win=[%{public}d, %{public}s]",
13774                     where, session->GetWindowId(), session->GetWindowName().c_str());
13775                 globalWinMode = globalWinMode | GlobalWindowMode::FLOAT;
13776             }
13777             if (globalWinMode == GlobalWindowMode::ALL) {
13778                 break;
13779             }
13780         }
13781         return WMError::WM_OK;
13782     }, __func__);
13783 }
13784 
GetTopNavDestinationName(int32_t windowId,std::string & topNavDestName)13785 WMError SceneSessionManager::GetTopNavDestinationName(int32_t windowId, std::string& topNavDestName)
13786 {
13787     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
13788         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
13789         return WMError::WM_ERROR_NOT_SYSTEM_APP;
13790     }
13791     auto session = GetSceneSession(windowId);
13792     if (session == nullptr) {
13793         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "no session with id: %{public}d", windowId);
13794         return WMError::WM_ERROR_INVALID_WINDOW;
13795     }
13796     if (!session->IsSessionForeground()) {
13797         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid operation: win=%{public}d, stat: %{public}u",
13798             session->GetWindowId(), static_cast<uint32_t>(session->GetSessionState()));
13799         return WMError::WM_ERROR_INVALID_OPERATION;
13800     }
13801     auto wsErrCode = session->GetTopNavDestinationName(topNavDestName);
13802     if (wsErrCode != WSError::WS_OK) {
13803         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get failed: win=%{public}d, errCode=%{public}d",
13804             session->GetWindowId(), static_cast<int32_t>(wsErrCode));
13805         return WMError::WM_ERROR_SYSTEM_ABNORMALLY;
13806     }
13807     return WMError::WM_OK;
13808 }
13809 
IsSessionInSpecificDisplay(const sptr<SceneSession> & session,DisplayId displayId) const13810 bool SceneSessionManager::IsSessionInSpecificDisplay(const sptr<SceneSession>& session, DisplayId displayId) const
13811 {
13812     if (session == nullptr) {
13813         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "session is null");
13814         return false;
13815     }
13816     if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(session->GetSessionProperty()->GetDisplayId()) &&
13817         (displayId == VIRTUAL_DISPLAY_ID || displayId == DEFAULT_DISPLAY_ID)) {
13818         bool isVirtualDisplay = displayId == VIRTUAL_DISPLAY_ID;
13819         if (isVirtualDisplay &&
13820             session->GetSessionRect().posY_ + session->GetSessionRect().height_ < GetFoldLowerScreenPosY()) {
13821             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "not in virtual display, win: [%{public}d, %{public}s]",
13822                 session->GetWindowId(), session->GetWindowName().c_str());
13823             return false;
13824         }
13825         if (!isVirtualDisplay && session->GetSessionRect().posY_ >= GetFoldLowerScreenPosY()) {
13826             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "in virtual display, win: [%{public}d, %{public}s]",
13827                 session->GetWindowId(), session->GetWindowName().c_str());
13828             return false;
13829         }
13830         return true;
13831     }
13832     return displayId == session->GetSessionProperty()->GetDisplayId();
13833 }
13834 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)13835 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
13836 {
13837     auto task = [this, &infos, where = __func__]() {
13838         for (auto [surfaceId, _] : lastVisibleData_) {
13839             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
13840             if (session == nullptr) {
13841                 continue;
13842             }
13843             WSRect hostRect = session->GetSessionRect();
13844             Rect rect = {hostRect.posX_, hostRect.posY_,
13845                          static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
13846             auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
13847                                                 session->GetSessionProperty());
13848             auto windowVisibilityInfo = sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
13849                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
13850                 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
13851                 session->IsFocused());
13852             windowVisibilityInfo->SetAppIndex(session->GetSessionInfo().appIndex_);
13853             windowVisibilityInfo->SetIsSystem(session->GetSessionInfo().isSystem_);
13854             windowVisibilityInfo->SetZOrder(session->GetZOrder());
13855             Rect globalDisplayRect = session->GetSessionProperty()->GetGlobalDisplayRect();
13856             windowVisibilityInfo->SetGlobalDisplayRect(globalDisplayRect);
13857             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: wid=%{public}d, globalDisplayRect=%{public}s",
13858                 where, static_cast<int32_t>(session->GetPersistentId()), globalDisplayRect.ToString().c_str());
13859             HookWindowInfo hookWindowInfo = GetAppHookWindowInfo(session->GetSessionInfo().bundleName_);
13860             if (hookWindowInfo.enableHookWindow &&
13861                 WindowHelper::IsMainWindow(session->GetWindowType()) &&
13862                 !MathHelper::NearEqual(hookWindowInfo.widthHookRatio, HookWindowInfo::DEFAULT_WINDOW_SIZE_HOOK_RATIO)) {
13863                 rect.width_ = static_cast<uint32_t>(rect.width_ * hookWindowInfo.widthHookRatio);
13864                 globalDisplayRect.width_ =
13865                     static_cast<uint32_t>(globalDisplayRect.width_ * hookWindowInfo.widthHookRatio);
13866                 windowVisibilityInfo->rect_ = rect;
13867                 windowVisibilityInfo->SetGlobalDisplayRect(globalDisplayRect);
13868                 TLOGD(WmsLogTag::WMS_LAYOUT, "%{public}s: id:%{public}u, hook window width, hooked width:%{public}u, "
13869                     "hooked globalDisplay width:%{public}u, widthHookRatio:%{public}f.", where,
13870                     session->GetPersistentId(), rect.width_, globalDisplayRect.width_, hookWindowInfo.widthHookRatio);
13871             }
13872             infos.emplace_back(windowVisibilityInfo);
13873         }
13874         return WMError::WM_OK;
13875     };
13876     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
13877 }
13878 
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)13879 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
13880 {
13881     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
13882     for (const auto& [id, session] : sceneSessionMap_) {
13883         if (session == nullptr) {
13884             continue;
13885         }
13886         uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
13887         windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
13888     }
13889 }
13890 
FlushWindowInfoToMMI(const bool forceFlush)13891 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
13892 {
13893     auto task = [this, forceFlush] {
13894         if (isUserBackground_) {
13895             TLOGND(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
13896             return;
13897         }
13898         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
13899         SceneInputManager::GetInstance().ResetSessionDirty();
13900         auto [windowInfoList, pixelMapList] = SceneInputManager::GetInstance().GetFullWindowInfoList();
13901         TLOGND(WmsLogTag::WMS_EVENT, "windowInfoList size: %{public}d", static_cast<int32_t>(windowInfoList.size()));
13902         SceneInputManager::GetInstance().
13903             FlushDisplayInfoToMMI(std::move(windowInfoList), std::move(pixelMapList), forceFlush);
13904     };
13905     TLOGD(WmsLogTag::WMS_EVENT, "in");
13906     taskScheduler_->PostAsyncTask(task, __func__);
13907 }
13908 
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string & taskName,const int delayTime)13909 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask&& task,
13910     const std::string& taskName, const int delayTime)
13911 {
13912     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
13913 }
13914 
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)13915 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
13916     int32_t& parentId)
13917 {
13918     // This function should be called in task
13919     auto iter = extSessionInfoMap_.find(token);
13920     if (iter == extSessionInfoMap_.end()) {
13921         return false;
13922     }
13923     persistentId = iter->second.persistentId;
13924     parentId = iter->second.parentId;
13925     return true;
13926 }
13927 
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession,bool isConstrainedModal)13928 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession, bool isConstrainedModal)
13929 {
13930     const char* const where = __func__;
13931     auto task = [this, remoteExtSession, isConstrainedModal, where]() {
13932         auto iter = remoteExtSessionMap_.find(remoteExtSession);
13933         if (iter == remoteExtSessionMap_.end()) {
13934             TLOGNI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession");
13935             return;
13936         }
13937         int32_t persistentId = INVALID_SESSION_ID;
13938         int32_t parentId = INVALID_SESSION_ID;
13939         auto abilityToken = iter->second;
13940         if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
13941             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
13942             return;
13943         }
13944 
13945         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d",
13946             where, persistentId, parentId);
13947         auto sceneSession = GetSceneSession(parentId);
13948         if (sceneSession != nullptr) {
13949             auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
13950             sceneSession->RemoveExtWindowFlags(persistentId);
13951             if (oldFlags.hideNonSecureWindowsFlag) {
13952                 HandleSecureSessionShouldHide(sceneSession);
13953             }
13954             if (oldFlags.waterMarkFlag) {
13955                 CheckAndNotifyWaterMarkChangedResult();
13956             }
13957             if (oldFlags.privacyModeFlag) {
13958                 UpdatePrivateStateAndNotify(parentId);
13959             }
13960             if (!isConstrainedModal) {
13961                 sceneSession->RemoveNormalModalUIExtension(persistentId);
13962             }
13963             sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
13964             sceneSession->RemoveExtensionTokenInfo(abilityToken);
13965         } else {
13966             ExtensionWindowFlags actions;
13967             actions.SetAllActive();
13968             HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
13969         }
13970         extSessionInfoMap_.erase(iter->second);
13971         remoteExtSessionMap_.erase(iter);
13972     };
13973     taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
13974 }
13975 
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)13976 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
13977 {
13978     auto pid = IPCSkeleton::GetCallingRealPid();
13979     const char* const where = __func__;
13980     auto task = [this, token, pid, rect, where]() {
13981         int32_t persistentId = INVALID_SESSION_ID;
13982         int32_t parentId = INVALID_SESSION_ID;
13983         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
13984             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
13985             return;
13986         }
13987         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
13988             "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
13989             where, pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
13990         auto parentSession = GetSceneSession(parentId);
13991         if (parentSession) {
13992             auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetClientRect().posX_;
13993             auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetClientRect().posY_;
13994             Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
13995             WSRect transRect = { globalRect.posX_, globalRect.posY_, globalRect.width_, globalRect.height_ };
13996             parentSession->TransformRelativeRectToGlobalRect(transRect);
13997             globalRect.posY_ = transRect.posY_;
13998             ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
13999             TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid: %{public}d, persistentId: %{public}d, "
14000                 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
14001                 where, pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
14002                 parentSession->GetSessionGlobalRect().ToString().c_str());
14003             parentSession->UpdateNormalModalUIExtension(extensionInfo);
14004         }
14005     };
14006     taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
14007 }
14008 
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)14009 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
14010 {
14011     auto pid = IPCSkeleton::GetCallingRealPid();
14012     const char* const where = __func__;
14013     auto task = [this, token, pid, posX, posY, where]() {
14014         int32_t persistentId = INVALID_SESSION_ID;
14015         int32_t parentId = INVALID_SESSION_ID;
14016         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
14017             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
14018             return;
14019         }
14020         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: pid=%{public}d, persistentId=%{public}d, "
14021             "parentId=%{public}d", where, pid, persistentId, parentId);
14022         auto parentSession = GetSceneSession(parentId);
14023         if (parentSession) {
14024             auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
14025             if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
14026                 modalUIExtensionEventInfo.value().persistentId == persistentId) {
14027                 parentSession->ProcessPointDownSession(posX, posY);
14028             }
14029         }
14030     };
14031     taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
14032 }
14033 
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId,bool isConstrainedModal)14034 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
14035     const sptr<IRemoteObject>& token, uint64_t surfaceNodeId, bool isConstrainedModal)
14036 {
14037     auto pid = IPCSkeleton::GetCallingRealPid();
14038     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
14039     const char* const where = __func__;
14040     auto task = [this, sessionStage, token, surfaceNodeId, isConstrainedModal, pid, callingTokenId, where]() {
14041         if (sessionStage == nullptr || token == nullptr) {
14042             TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
14043             return;
14044         }
14045         auto remoteExtSession = sessionStage->AsObject();
14046         if (remoteExtSession == nullptr) {
14047             TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
14048             return;
14049         }
14050         if (extensionDeath_ == nullptr) {
14051             TLOGNE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
14052             return;
14053         }
14054         if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
14055             TLOGNE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
14056             return;
14057         }
14058 
14059         AAFwk::UIExtensionSessionInfo info;
14060         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
14061         if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
14062             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
14063             return;
14064         }
14065 
14066         int32_t persistentId = info.persistentId;
14067         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
14068         UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
14069         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: persistentId=%{public}d, parentId=%{public}d, "
14070             "usage=%{public}u, surfaceNodeId=%{public}" PRIu64 ", pid=%{public}d",
14071             where, persistentId, parentId, usage, surfaceNodeId, pid);
14072 
14073         remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
14074         extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
14075 
14076         auto parentSession = GetSceneSession(parentId);
14077         if (!parentSession) {
14078             TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
14079             return;
14080         }
14081 
14082         UIExtensionTokenInfo tokenInfo;
14083         tokenInfo.abilityToken = token;
14084         tokenInfo.callingTokenId = callingTokenId;
14085         tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
14086             info.extensionAbilityType);
14087         parentSession->AddExtensionTokenInfo(tokenInfo);
14088         parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
14089         if (usage == UIExtensionUsage::MODAL && parentSession->GetCallingPid() != GetPid()) {
14090             ExtensionWindowEventInfo extensionInfo {
14091                 .persistentId = persistentId,
14092                 .pid = pid,
14093             };
14094             if (!isConstrainedModal) {
14095                 parentSession->AddNormalModalUIExtension(extensionInfo);
14096             }
14097         }
14098     };
14099     taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
14100 }
14101 
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,bool isConstrainedModal)14102 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
14103     const sptr<IRemoteObject>& token, bool isConstrainedModal)
14104 {
14105     TLOGD(WmsLogTag::WMS_UIEXT, "in");
14106     auto task = [this, sessionStage, token, isConstrainedModal]() {
14107         if (sessionStage == nullptr || token == nullptr) {
14108             TLOGNE(WmsLogTag::WMS_UIEXT, "input is nullptr");
14109             return;
14110         }
14111         auto remoteExtSession = sessionStage->AsObject();
14112         if (remoteExtSession == nullptr) {
14113             TLOGNE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
14114             return;
14115         }
14116         auto iter = remoteExtSessionMap_.find(remoteExtSession);
14117         if (iter == remoteExtSessionMap_.end() || iter->second != token) {
14118             TLOGNE(WmsLogTag::WMS_UIEXT, "token not match");
14119             return;
14120         }
14121 
14122         DestroyExtensionSession(remoteExtSession, isConstrainedModal);
14123     };
14124     taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
14125 }
14126 
CalculateCombinedExtWindowFlags()14127 void SceneSessionManager::CalculateCombinedExtWindowFlags()
14128 {
14129     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
14130     combinedExtWindowFlags_.bitData = 0;
14131     for (const auto& iter: extWindowFlagsMap_) {
14132         combinedExtWindowFlags_.bitData |= iter.second.bitData;
14133     }
14134     specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
14135 }
14136 
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)14137 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
14138     ExtensionWindowFlags actions)
14139 {
14140     auto iter = extWindowFlagsMap_.find(persistentId);
14141     // Each flag is false when inactive, 0 means all flags are inactive
14142     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
14143     ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
14144     if (newFlags.bitData == 0) {
14145         extWindowFlagsMap_.erase(persistentId);
14146     } else {
14147         extWindowFlagsMap_[persistentId] = newFlags;
14148     }
14149     CalculateCombinedExtWindowFlags();
14150 }
14151 
HideNonSecureFloatingWindows()14152 void SceneSessionManager::HideNonSecureFloatingWindows()
14153 {
14154     if (systemConfig_.IsPcWindow()) {
14155         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
14156         return;
14157     }
14158     bool shouldHide = false;
14159     {
14160         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14161         for (const auto& iter: sceneSessionMap_) {
14162             auto& session = iter.second;
14163             if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
14164                 shouldHide = true;
14165                 break;
14166             }
14167         }
14168     }
14169     if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
14170         TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
14171         shouldHide = true;
14172     }
14173     if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
14174         return;
14175     }
14176 
14177     shouldHideNonSecureFloatingWindows_.store(shouldHide);
14178     for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
14179         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
14180             session->NotifyForceHideChange(shouldHide);
14181             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
14182                 session->GetWindowName().c_str(), persistentId, shouldHide);
14183         }
14184     }
14185 }
14186 
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)14187 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
14188 {
14189     // don't let sub-window show when switching secure host window to background
14190     if (!sceneSession->IsSessionForeground()) {
14191         return;
14192     }
14193 
14194     auto parentId = sceneSession->GetPersistentId();
14195     bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
14196     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14197     for (const auto& [_, session] : sceneSessionMap_) {
14198         if (!session) {
14199             continue;
14200         }
14201         auto sessionProperty = session->GetSessionProperty();
14202         if (sessionProperty->GetParentPersistentId() != parentId) {
14203             continue;
14204         }
14205         if (SessionHelper::IsNonSecureToUIExtension(sessionProperty->GetWindowType()) &&
14206             !session->IsSystemSpecificSession()) {
14207             session->NotifyForceHideChange(shouldHide);
14208             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
14209                 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
14210         }
14211     }
14212 }
14213 
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)14214 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
14215 {
14216     if (sceneSession == nullptr) {
14217         TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
14218         return WSError::WS_ERROR_INVALID_SESSION;
14219     }
14220 
14221     HideNonSecureFloatingWindows();
14222     HideNonSecureSubWindows(sceneSession);
14223     return WSError::WS_OK;
14224 }
14225 
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)14226 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
14227     ExtensionWindowFlags actions)
14228 {
14229     UpdateSpecialExtWindowFlags(persistentId, flags, actions);
14230     if (actions.waterMarkFlag) {
14231         CheckAndNotifyWaterMarkChangedResult();
14232     }
14233     if (actions.hideNonSecureWindowsFlag) {
14234         HideNonSecureFloatingWindows();
14235     }
14236     if (actions.privacyModeFlag) {
14237         UpdatePrivateStateAndNotifyForAllScreens();
14238     }
14239 }
14240 
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)14241 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
14242 {
14243     TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
14244     if (!SessionPermission::IsSystemCalling()) {
14245         TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
14246         return WSError::WS_ERROR_NOT_SYSTEM_APP;
14247     }
14248     const auto callingPid = IPCSkeleton::GetCallingRealPid();
14249     const char* const where = __func__;
14250     auto task = [this, persistentId, shouldHide, callingPid, where]() {
14251         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14252         auto iter = sceneSessionMap_.find(persistentId);
14253         if (iter == sceneSessionMap_.end()) {
14254             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Session with persistentId %{public}d not found",
14255                 where, persistentId);
14256             return WSError::WS_ERROR_INVALID_SESSION;
14257         }
14258         auto sceneSession = iter->second;
14259         if (sceneSession == nullptr) {
14260             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: sceneSession is nullptr.", where);
14261             return WSError::WS_ERROR_NULLPTR;
14262         }
14263         if (callingPid != sceneSession->GetCallingPid()) {
14264             TLOGNE(WmsLogTag::WMS_UIEXT, "%{public}s: Permission denied", where);
14265             return WSError::WS_ERROR_INVALID_PERMISSION;
14266         }
14267         sceneSession->SetShouldHideNonSecureWindows(shouldHide);
14268         return HandleSecureSessionShouldHide(sceneSession);
14269     };
14270 
14271     taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
14272     return WSError::WS_OK;
14273 }
14274 
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const14275 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
14276 {
14277     auto ret = WSError::WS_OK;
14278     bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
14279     if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
14280         actions.hideNonSecureWindowsFlag = false;
14281         actions.waterMarkFlag = false;
14282         TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
14283         ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
14284     }
14285     auto needPrivacyWindow = actions.privacyModeFlag;
14286     if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
14287         actions.privacyModeFlag = false;
14288         TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
14289         ret = WSError::WS_ERROR_INVALID_PERMISSION;
14290     }
14291     return ret;
14292 }
14293 
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)14294 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
14295     uint32_t extWindowActions)
14296 {
14297     ExtensionWindowFlags actions(extWindowActions);
14298     auto ret = CheckExtWindowFlagsPermission(actions);
14299     if (ret != WSError::WS_OK) {
14300         return ret;
14301     }
14302 
14303     ExtensionWindowFlags flags(extWindowFlags);
14304     const char* const where = __func__;
14305     auto task = [this, token, flags, actions, where]() {
14306         int32_t persistentId = INVALID_SESSION_ID;
14307         int32_t parentId = INVALID_SESSION_ID;
14308         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
14309             TLOGNE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
14310             return WSError::WS_ERROR_INVALID_OPERATION;
14311         }
14312 
14313         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s: parentId=%{public}d, persistentId=%{public}d, "
14314             "extWindowFlags=%{public}d, actions=%{public}d", where, parentId, persistentId,
14315             flags.bitData, actions.bitData);
14316         auto sceneSession = GetSceneSession(parentId);
14317         if (sceneSession == nullptr) {
14318             TLOGND(WmsLogTag::WMS_UIEXT, "%{public}s: Parent session with persistentId %{public}d not found",
14319                 where, parentId);
14320             HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
14321             return WSError::WS_OK;
14322         }
14323 
14324         auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
14325         sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
14326         auto newFlags = sceneSession->GetCombinedExtWindowFlags();
14327         if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
14328             HandleSecureSessionShouldHide(sceneSession);
14329         }
14330         if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
14331             CheckAndNotifyWaterMarkChangedResult();
14332         }
14333         if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
14334             UpdatePrivateStateAndNotify(parentId);
14335         }
14336         return WSError::WS_OK;
14337     };
14338 
14339     taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
14340     return ret;
14341 }
14342 
GetHostWindowRect(int32_t hostWindowId,Rect & rect)14343 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
14344 {
14345     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
14346     if (!SessionPermission::IsSystemCalling()) {
14347         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
14348         return WSError::WS_ERROR_NOT_SYSTEM_APP;
14349     }
14350     auto task = [this, hostWindowId, &rect]() {
14351         auto sceneSession = GetSceneSession(hostWindowId);
14352         if (sceneSession == nullptr) {
14353             TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
14354             return WSError::WS_ERROR_INVALID_SESSION;
14355         }
14356         WSRect hostRect = sceneSession->GetSessionScreenRelativeRect();
14357         auto currScreenFoldStatus = PcFoldScreenManager::GetInstance().GetScreenFoldStatus();
14358         auto needTransRect = currScreenFoldStatus != SuperFoldStatus::UNKNOWN &&
14359             currScreenFoldStatus != SuperFoldStatus::FOLDED && currScreenFoldStatus != SuperFoldStatus::EXPANDED;
14360         auto isSystemKeyboard = sceneSession->GetSessionProperty() != nullptr &&
14361             sceneSession->GetSessionProperty()->IsSystemKeyboard();
14362         if (!isSystemKeyboard && needTransRect) {
14363             WSRect globalRect = hostRect;
14364             sceneSession->TransformGlobalRectToRelativeRect(hostRect);
14365             TLOGI(WmsLogTag::WMS_UIEXT, "Transform globalRect: %{public}s to relativeRect: %{public}s",
14366                 globalRect.ToString().c_str(), hostRect.ToString().c_str());
14367         }
14368         rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
14369         return WSError::WS_OK;
14370     };
14371     taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
14372     return WSError::WS_OK;
14373 }
14374 
GetHostGlobalScaledRect(int32_t hostWindowId,Rect & globalScaledRect)14375 WSError SceneSessionManager::GetHostGlobalScaledRect(int32_t hostWindowId, Rect& globalScaledRect)
14376 {
14377     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
14378     auto sceneSession = GetSceneSession(hostWindowId);
14379     if (sceneSession == nullptr) {
14380         TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
14381         return WSError::WS_ERROR_INVALID_SESSION;
14382     }
14383     sceneSession->GetGlobalScaledRect(globalScaledRect);
14384     return WSError::WS_OK;
14385 }
14386 
ReclaimPurgeableCleanMem()14387 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
14388 {
14389 #ifdef MEMMGR_WINDOW_ENABLE
14390     return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
14391 #else
14392     return -1;
14393 #endif
14394 }
14395 
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)14396 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
14397     const std::vector<VisibleWindowNumInfo>& currentInfo)
14398 {
14399     if (lastInfo.size() != currentInfo.size()) {
14400         TLOGE(WmsLogTag::DEFAULT, "last and current info is not Same");
14401         return false;
14402     }
14403     int sizeOfLastInfo = static_cast<int>(lastInfo.size());
14404     for (int i = 0; i < sizeOfLastInfo; i++) {
14405         if (lastInfo[i].displayId != currentInfo[i].displayId ||
14406             lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
14407             TLOGE(WmsLogTag::DEFAULT, "last and current visible window num is not Same");
14408             return false;
14409         }
14410     }
14411     return true;
14412 }
14413 
CacVisibleWindowNum()14414 void SceneSessionManager::CacVisibleWindowNum()
14415 {
14416     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
14417     {
14418         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14419         sceneSessionMapCopy = sceneSessionMap_;
14420     }
14421     std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
14422     bool isFullScreen = true;
14423     for (const auto& elem : sceneSessionMapCopy) {
14424         auto curSession = elem.second;
14425         if (curSession == nullptr) {
14426             continue;
14427         }
14428         bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
14429             curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
14430         if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
14431             continue;
14432         }
14433 
14434         bool isWindowVisible = curSession->GetRSVisible();
14435         if (isWindowVisible) {
14436             auto windowMode = curSession->GetWindowMode();
14437             if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
14438                 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
14439                 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
14440                 isFullScreen = false;
14441             }
14442             int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
14443             auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
14444                 [displayId](const VisibleWindowNumInfo& info) {
14445                     return (static_cast<int32_t>(info.displayId)) == displayId;
14446                 });
14447             if (it == visibleWindowNumInfo.end()) {
14448                 visibleWindowNumInfo.push_back({displayId, 1});
14449             } else {
14450                 it->visibleWindowNum++;
14451             }
14452         }
14453     }
14454     if (isFullScreen) {
14455         std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
14456                       [](auto& info) { info.visibleWindowNum = 1; });
14457     }
14458     std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
14459     if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
14460         SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
14461         lastInfo_ = visibleWindowNumInfo;
14462     }
14463 }
14464 
ReportWindowProfileInfos()14465 void SceneSessionManager::ReportWindowProfileInfos()
14466 {
14467     enum class WindowVisibleState : int32_t {
14468         FOCUSBLE = 0,
14469         FULLY_VISIBLE,
14470         MINIMIZED,
14471         TOTALLY_OCCLUSION,
14472         PARTLY_OCCLUSION
14473     };
14474     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
14475     {
14476         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14477         sceneSessionMapCopy = sceneSessionMap_;
14478     }
14479     auto focusWindowId = GetFocusedSessionId();
14480     for (const auto& [_, currSession] : sceneSessionMapCopy) {
14481         if (currSession == nullptr || currSession->GetSessionInfo().isSystem_ ||
14482             currSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
14483             continue;
14484         }
14485         WindowProfileInfo windowProfileInfo;
14486         WSRect rect = currSession->GetSessionRect();
14487         std::stringstream rectStr;
14488         rectStr << "[" << rect.posX_ << " " << rect.posY_ << " " << rect.width_ << " " << rect.height_ << "]";
14489         windowProfileInfo.rect = rectStr.str();
14490         windowProfileInfo.zorder = static_cast<int32_t>(currSession->GetZOrder());
14491         windowProfileInfo.bundleName = currSession->GetSessionInfo().bundleName_;
14492         windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
14493             currSession->GetSessionProperty()->GetDisplayId());
14494         windowProfileInfo.windowSceneMode = static_cast<int32_t>(currSession->GetWindowMode());
14495         if (focusWindowId == static_cast<int32_t>(currSession->GetWindowId())) {
14496             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
14497         } else if (currSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
14498             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
14499         } else if (currSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
14500             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::TOTALLY_OCCLUSION);
14501         } else if (currSession->GetVisibilityState() == WINDOW_VISIBILITY_STATE_NO_OCCLUSION) {
14502             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FULLY_VISIBLE);
14503         } else {
14504             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::PARTLY_OCCLUSION);
14505         }
14506         WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
14507         TLOGD(WmsLogTag::DEFAULT,
14508               "bundleName:%{public}s, windowVisibleState:%{public}d, windowLocatedScreen:%{public}d, "
14509               "windowSceneMode:%{public}d, windowZorder:%{public}d, windowRect:%{public}s",
14510               windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
14511               windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode,
14512               windowProfileInfo.zorder, windowProfileInfo.rect.c_str());
14513     }
14514 }
14515 
GetCustomDecorHeight(int32_t persistentId)14516 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
14517 {
14518     int32_t height = 0;
14519     auto sceneSession = GetSceneSession(persistentId);
14520     if (sceneSession == nullptr) {
14521         TLOGE(WmsLogTag::WMS_DECOR, "session is invalid, id: %{public}d", persistentId);
14522         return 0;
14523     }
14524     height = sceneSession->GetCustomDecorHeight();
14525     TLOGD(WmsLogTag::WMS_DECOR, "decor height: %{public}d", height);
14526     return height;
14527 }
14528 
RemoveFailRecoveredSession()14529 void SceneSessionManager::RemoveFailRecoveredSession()
14530 {
14531     for (const auto persistentId : failRecoveredPersistentIdSet_) {
14532         auto sceneSession = GetSceneSession(persistentId);
14533         if (sceneSession == nullptr) {
14534             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId=%{public}d", persistentId);
14535             continue;
14536         }
14537         if (!sceneSession->IsRecovered()) {
14538             TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId=%{public}d", persistentId);
14539             continue;
14540         }
14541         TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId=%{public}d", persistentId);
14542         ExceptionInfo exceptionInfo;
14543         exceptionInfo.needRemoveSession = true;
14544         sceneSession->NotifySessionExceptionInner(SetAbilitySessionInfo(sceneSession), exceptionInfo);
14545     }
14546     failRecoveredPersistentIdSet_.clear();
14547 }
14548 
GetDisplayRegion(DisplayId displayId)14549 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
14550 {
14551     if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
14552         return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
14553     }
14554     TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
14555     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
14556     if (display == nullptr) {
14557         TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
14558         return nullptr;
14559     }
14560     auto displayInfo = display->GetDisplayInfo();
14561     if (displayInfo == nullptr) {
14562         TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
14563         return nullptr;
14564     }
14565     int32_t displayWidth = displayInfo->GetWidth();
14566     int32_t displayHeight = displayInfo->GetHeight();
14567     if (displayWidth == 0 || displayHeight == 0) {
14568         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
14569         return nullptr;
14570     }
14571     if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
14572         const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
14573             PcFoldScreenManager::GetInstance().GetDisplayRects();
14574         displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
14575         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
14576     }
14577     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
14578     auto region = std::make_shared<SkRegion>(rect);
14579     displayRegionMap_[displayId] = region;
14580     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w=%{public}d, h=%{public}d", displayWidth, displayHeight);
14581     return std::make_shared<SkRegion>(rect);
14582 }
14583 
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)14584 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
14585 {
14586     if (displayInfo == nullptr) {
14587         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "update display region failed, displayInfo is nullptr.");
14588         return;
14589     }
14590     auto displayId = displayInfo->GetDisplayId();
14591     int32_t displayWidth = displayInfo->GetWidth();
14592     int32_t displayHeight = displayInfo->GetHeight();
14593     if (displayWidth == 0 || displayHeight == 0) {
14594         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid display size of display: %{public}" PRIu64, displayId);
14595         return;
14596     }
14597     if (PcFoldScreenManager::GetInstance().IsHalfFolded(displayId)) {
14598         const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] =
14599             PcFoldScreenManager::GetInstance().GetDisplayRects();
14600         displayHeight = virtualDisplayRect.posY_ + virtualDisplayRect.height_;
14601         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "update display height in pc fold");
14602     }
14603     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
14604     auto region = std::make_shared<SkRegion>(rect);
14605     displayRegionMap_[displayId] = region;
14606     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "update display region to w: %{public}d, h: %{public}d",
14607         displayWidth, displayHeight);
14608 }
14609 
GetDisplaySizeById(DisplayId displayId,int32_t & displayWidth,int32_t & displayHeight)14610 bool SceneSessionManager::GetDisplaySizeById(DisplayId displayId, int32_t& displayWidth, int32_t& displayHeight)
14611 {
14612     auto region = GetDisplayRegion(displayId);
14613     if (region == nullptr) {
14614         TLOGW(WmsLogTag::WMS_LAYOUT, "failed, displayId:%{public}" PRIu64, displayId);
14615         return false;
14616     }
14617     const SkIRect& rect = region->getBounds();
14618     displayWidth = rect.fRight;
14619     displayHeight = rect.fBottom;
14620     return true;
14621 }
14622 
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)14623 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
14624 {
14625     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
14626     for (const auto& [_, sceneSession] : sceneSessionMap_) {
14627         if (sceneSession == nullptr) {
14628             TLOGW(WmsLogTag::WMS_ATTRIBUTE, "session is null");
14629             continue;
14630         }
14631         if (Session::IsScbCoreEnabled()) {
14632             if (!sceneSession->IsVisibleForAccessibility()) {
14633                 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "unvisible: isSys=%{public}d, inWid=%{public}d, bundle=%{public}s, "
14634                     "zOrder=%{public}u, displayId=%{public}" PRIu64 ", nodeId=%{public}d, "
14635                     "sysTouchable=%{public}d, interactive=%{public}d, visibleForeground=%{public}d",
14636                     sceneSession->GetSessionInfo().isSystem_, static_cast<int32_t>(sceneSession->GetPersistentId()),
14637                     sceneSession->GetSessionInfo().bundleName_.c_str(), sceneSession->GetZOrder(),
14638                     sceneSession->GetSessionProperty()->GetDisplayId(), sceneSession->GetUINodeId(),
14639                     sceneSession->GetSystemTouchable(), sceneSession->GetForegroundInteractiveStatus(),
14640                     sceneSession->IsVisibleForeground());
14641                 continue;
14642             }
14643         } else {
14644             if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
14645                 TLOGD(WmsLogTag::WMS_ATTRIBUTE, "unvisible2: isSys=%{public}d, inWid=%{public}d, bundle=%{public}s, "
14646                     "zOrder=%{public}u, displayId=%{public}" PRIu64 ", nodeId=%{public}d, "
14647                     "sysTouchable=%{public}d, interactive=%{public}d, visibleForeground=%{public}d",
14648                     sceneSession->GetSessionInfo().isSystem_, static_cast<int32_t>(sceneSession->GetPersistentId()),
14649                     sceneSession->GetSessionInfo().bundleName_.c_str(), sceneSession->GetZOrder(),
14650                     sceneSession->GetSessionProperty()->GetDisplayId(), sceneSession->GetUINodeId(),
14651                     sceneSession->GetSystemTouchable(), sceneSession->GetForegroundInteractiveStatus(),
14652                     sceneSession->IsVisibleForeground());
14653                 continue;
14654             }
14655         }
14656         if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
14657             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
14658             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
14659             continue;
14660         }
14661         if (sceneSession->GetSessionInfo().bundleName_.find("SCBDragScale") != std::string::npos) {
14662             continue;
14663         }
14664         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "isSys=%{public}d, inWid=%{public}d, bundle=%{public}s, zOrder=%{public}u",
14665             sceneSession->GetSessionInfo().isSystem_, static_cast<int32_t>(sceneSession->GetPersistentId()),
14666             sceneSession->GetSessionInfo().bundleName_.c_str(), sceneSession->GetZOrder());
14667         sceneSessionList.push_back(sceneSession);
14668     }
14669 }
14670 
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)14671 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
14672     std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
14673 {
14674     for (const auto& sceneSession : sceneSessionList) {
14675         if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
14676             TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
14677         }
14678     }
14679 }
14680 
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)14681 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
14682 {
14683     std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
14684         return a->GetZOrder() > b->GetZOrder();
14685     });
14686     std::vector<sptr<SceneSession>> result;
14687     std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
14688     for (const auto& sceneSession : sceneSessionList) {
14689         if (sceneSession == nullptr) {
14690             TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
14691             continue;
14692         }
14693         std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
14694         auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
14695         if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
14696             unaccountedSpace = unaccountedSpaceMap[displayId];
14697         } else {
14698             unaccountedSpace = GetDisplayRegion(displayId);
14699             if (unaccountedSpace == nullptr) {
14700                 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
14701                 continue;
14702             }
14703             unaccountedSpaceMap[displayId] = unaccountedSpace;
14704         }
14705         if (SubtractIntersectArea(unaccountedSpace, sceneSession)) {
14706             result.push_back(sceneSession);
14707         }
14708         if (unaccountedSpace->isEmpty()) {
14709             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "break after: inWid=%{public}d, zOrder=%{public}u",
14710                 static_cast<int32_t>(sceneSession->GetPersistentId()), sceneSession->GetZOrder());
14711             break;
14712         }
14713     }
14714     sceneSessionList = result;
14715 }
14716 
SubtractIntersectArea(std::shared_ptr<SkRegion> & unaccountedSpace,const sptr<SceneSession> & sceneSession)14717 bool SceneSessionManager::SubtractIntersectArea(std::shared_ptr<SkRegion>& unaccountedSpace,
14718     const sptr<SceneSession>& sceneSession)
14719 {
14720     if (unaccountedSpace == nullptr || sceneSession == nullptr) {
14721         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "space or session is null");
14722         return false;
14723     }
14724     auto hotAreas = sceneSession->GetTouchHotAreas();
14725     WSRect wsRect = sceneSession->GetSessionRect();
14726     for (auto& rect : hotAreas) {
14727         TLOGD(WmsLogTag::WMS_ATTRIBUTE, "id=%{public}d, rect=%{public}s, hotArea=%{public}s",
14728             static_cast<int32_t>(sceneSession->GetPersistentId()), wsRect.ToString().c_str(), rect.ToString().c_str());
14729         if (rect != Rect::EMPTY_RECT) {
14730             rect.posX_ += wsRect.posX_;
14731             rect.posY_ += wsRect.posY_;
14732         }
14733     }
14734     if (hotAreas.empty()) {
14735         hotAreas.push_back({.posX_ = wsRect.posX_, .posY_ = wsRect.posY_,
14736                             .width_ = wsRect.width_, .height_ = wsRect.height_});
14737     }
14738     bool hasIntersectArea = false;
14739     for (const auto& rect : hotAreas) {
14740         SkIRect windowBounds {.fLeft = rect.posX_, .fTop = rect.posY_,
14741                               .fRight = rect.posX_ + rect.width_, .fBottom = rect.posY_ + rect.height_};
14742         SkRegion windowRegion(windowBounds);
14743         if (unaccountedSpace->quickReject(windowRegion)) {
14744             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "quick reject: inWid=%{public}d, "
14745                 "bounds=[l=%{public}d, t=%{public}d, r=%{public}d, b=%{public}d]",
14746                 static_cast<int32_t>(sceneSession->GetPersistentId()),
14747                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
14748             continue;
14749         }
14750         if (!unaccountedSpace->intersects(windowRegion)) {
14751             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "no intersects: inWid=%{public}d, "
14752                 "bounds=[l=%{public}d, t=%{public}d, r=%{public}d, b=%{public}d]",
14753                 static_cast<int32_t>(sceneSession->GetPersistentId()),
14754                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
14755             continue;
14756         }
14757         hasIntersectArea = true;
14758         unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
14759         if (unaccountedSpace->isEmpty()) {
14760             TLOGD(WmsLogTag::WMS_ATTRIBUTE, "break hot area: inWid=%{public}d, "
14761                 "bounds=[l=%{public}d, t=%{public}d, r=%{public}d, b=%{public}d]",
14762                 static_cast<int32_t>(sceneSession->GetPersistentId()),
14763                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
14764             break;
14765         }
14766     }
14767     return hasIntersectArea;
14768 }
14769 
NotifyAllAccessibilityInfo()14770 void SceneSessionManager::NotifyAllAccessibilityInfo()
14771 {
14772     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyAllAccessibilityInfo");
14773     if (isUserBackground_) {
14774         TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
14775         return;
14776     }
14777     std::vector<sptr<SceneSession>> sceneSessionList;
14778     GetAllSceneSessionForAccessibility(sceneSessionList);
14779     FilterSceneSessionCovered(sceneSessionList);
14780 
14781     std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
14782     FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
14783 
14784     for (const auto& item : accessibilityInfo) {
14785         TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid=%{public}d, inWid=%{public}d, "
14786             "bundle=%{public}s,bounds=(x=%{public}d, y=%{public}d, w=%{public}d, h=%{public}d)",
14787             item->wid_, item->innerWid_, item->bundleName_.c_str(),
14788             item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
14789         for (const auto& rect : item->touchHotAreas_) {
14790             TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d,"
14791                 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
14792         }
14793     }
14794 
14795     SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
14796         WindowUpdateType::WINDOW_UPDATE_ALL);
14797 }
14798 
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)14799 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
14800     const sptr<WindowSessionProperty>& property)
14801 {
14802     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
14803     if (property == nullptr) {
14804         return windowStatus;
14805     }
14806     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
14807         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
14808         if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
14809             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
14810         }
14811     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
14812         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
14813     } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
14814         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
14815     } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
14816         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
14817     }
14818     return windowStatus;
14819 }
14820 
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)14821 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
14822 {
14823     if (!SessionPermission::IsStartedByInputMethod()) {
14824         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
14825         return WMError::WM_ERROR_INVALID_PERMISSION;
14826     }
14827     auto sceneSession = GetSceneSession(persistentId);
14828     if (sceneSession == nullptr) {
14829         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
14830         return WMError::WM_ERROR_NULLPTR;
14831     }
14832     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
14833     auto focusedSessionId = GetFocusedSessionId(displayId);
14834     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
14835         persistentId, sceneSession->GetWindowType());
14836     uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
14837     auto callingSession = GetSceneSession(callingWindowId);
14838     if (callingSession == nullptr) {
14839         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
14840         callingSession = GetSceneSession(focusedSessionId);
14841         if (callingSession == nullptr) {
14842             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
14843             return WMError::WM_ERROR_INVALID_WINDOW;
14844         }
14845     }
14846     if (callingSession->IsSystemSession()) {
14847         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
14848     } else {
14849         windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
14850             callingSession->GetSessionProperty());
14851     }
14852     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
14853         persistentId, windowStatus);
14854     return WMError::WM_OK;
14855 }
14856 
GetCallingWindowRect(int32_t persistentId,Rect & rect)14857 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
14858 {
14859     if (!SessionPermission::IsStartedByInputMethod()) {
14860         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
14861         return WMError::WM_ERROR_INVALID_PERMISSION;
14862     }
14863     auto sceneSession = GetSceneSession(persistentId);
14864     if (sceneSession == nullptr) {
14865         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is null, persistentId: %{public}d", persistentId);
14866         return WMError::WM_ERROR_NULLPTR;
14867     }
14868     auto displayId = sceneSession->GetSessionProperty()->GetDisplayId();
14869     auto focusedSessionId = GetFocusedSessionId(displayId);
14870     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
14871         persistentId, sceneSession->GetWindowType());
14872     uint32_t callingWindowId = sceneSession->GetSessionProperty()->GetCallingSessionId();
14873     auto callingSession = GetSceneSession(callingWindowId);
14874     if (callingSession == nullptr) {
14875         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
14876         callingSession = GetSceneSession(focusedSessionId);
14877         if (callingSession == nullptr) {
14878             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
14879             return WMError::WM_ERROR_INVALID_WINDOW;
14880         }
14881     }
14882     WSRect sessionRect = callingSession->GetSessionRect();
14883     rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
14884     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
14885         "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
14886     return WMError::WM_OK;
14887 }
14888 
GetWindowModeType(WindowModeType & windowModeType)14889 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
14890 {
14891     if (!SessionPermission::IsSACalling()) {
14892         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
14893         return WMError::WM_ERROR_INVALID_PERMISSION;
14894     }
14895     windowModeType = CheckWindowModeType();
14896     return WMError::WM_OK;
14897 }
14898 
GetWindowStyleType(WindowStyleType & windowStyleType)14899 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
14900 {
14901     if (!SessionPermission::IsSACalling()) {
14902         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
14903         return WMError::WM_ERROR_INVALID_PERMISSION;
14904     }
14905     if (systemConfig_.IsPcWindow()) {
14906         windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
14907         return WMError::WM_OK;
14908     }
14909     windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
14910         WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
14911     return WMError::WM_OK;
14912 }
14913 
CheckSceneZOrder()14914 void SceneSessionManager::CheckSceneZOrder()
14915 {
14916     auto task = [this]() {
14917         AnomalyDetection::SceneZOrderCheckProcess();
14918     };
14919     taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
14920 }
14921 
NotifyEnterRecentTask(bool enterRecent)14922 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
14923 {
14924     TLOGD(WmsLogTag::WMS_IMMS, "enterRecent %{public}u", enterRecent);
14925     enterRecent_.store(enterRecent);
14926     SetSystemAnimatedScenes(enterRecent ?
14927         SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
14928     auto task = [this] {
14929         for (auto persistentId : gestureBackEnableWindowIdSet_) {
14930             auto sceneSession = GetSceneSession(persistentId);
14931             if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
14932                 continue;
14933             }
14934             UpdateGestureBackEnabled(persistentId);
14935         }
14936     };
14937     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
14938     return WSError::WS_OK;
14939 }
14940 
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)14941 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
14942 {
14943     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
14944         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
14945         return WMError::WM_ERROR_INVALID_PERMISSION;
14946     }
14947 
14948     if (!topNInfo.empty() || (topNum <= 0)) {
14949         return WMError::WM_ERROR_INVALID_PARAM;
14950     }
14951 
14952     TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
14953     auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
14954         if (session == nullptr) {
14955             return false;
14956         }
14957 
14958         if (topNum == 0) {
14959             return true;
14960         }
14961 
14962         if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
14963             TLOGND(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
14964             return false;
14965         }
14966 
14967         MainWindowInfo info;
14968         info.pid_ = session->GetCallingPid();
14969         info.bundleName_ = session->GetSessionInfo().bundleName_;
14970         topNInfo.push_back(info);
14971         topNum--;
14972         TLOGNE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
14973             topNum, info.pid_, info.bundleName_.c_str());
14974         return false;
14975     };
14976     TraverseSessionTree(func, true);
14977 
14978     return WMError::WM_OK;
14979 }
14980 
GetCallingWindowInfo(CallingWindowInfo & callingWindowInfo)14981 WMError SceneSessionManager::GetCallingWindowInfo(CallingWindowInfo& callingWindowInfo)
14982 {
14983     int32_t curUserId = GetUserIdByUid(getuid());
14984     if (curUserId != callingWindowInfo.userId_) {
14985         TLOGE(WmsLogTag::WMS_KEYBOARD, "Target user not exists, targetUserId: %{public}d, curUserId: %{public}d, id: %{public}d",
14986             callingWindowInfo.userId_, curUserId, callingWindowInfo.windowId_);
14987         return WMError::WM_ERROR_INVALID_PARAM;
14988     }
14989     auto sceneSession = GetSceneSession(callingWindowInfo.windowId_);
14990     if (sceneSession == nullptr) {
14991         TLOGE(WmsLogTag::WMS_KEYBOARD, "sceneSession is nullptr, id: %{public}d", callingWindowInfo.windowId_);
14992         return WMError::WM_ERROR_NULLPTR;
14993     }
14994     callingWindowInfo.callingPid_ = sceneSession->GetCallingPid();
14995     callingWindowInfo.displayId_ = sceneSession->GetSessionProperty()->GetDisplayId();
14996     if (sceneSession->IsPcFoldDevice() && PcFoldScreenManager::GetInstance().IsHalfFolded(callingWindowInfo.displayId_)) {
14997         callingWindowInfo.displayId_ = sceneSession->GetClientDisplayId();
14998     }
14999     TLOGI(WmsLogTag::WMS_KEYBOARD, "info: [id: %{public}d, pid: %{public}d, "
15000         "displayId: %{public}" PRIu64" , userId: %{public}d]", callingWindowInfo.windowId_,
15001         callingWindowInfo.callingPid_, callingWindowInfo.displayId_, callingWindowInfo.userId_);
15002     return WMError::WM_OK;
15003 }
15004 
NotifyDisplayIdChanged(int32_t persistentId,uint64_t displayId)15005 void SceneSessionManager::NotifyDisplayIdChanged(int32_t persistentId, uint64_t displayId)
15006 {
15007     auto sceneSession = GetSceneSession(persistentId);
15008     if (!sceneSession) {
15009         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
15010         return;
15011     }
15012     // Find keyboard session.
15013     const auto& keyboardSessionVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
15014     for (const auto& keyboardSession : keyboardSessionVec) {
15015         if (!keyboardSession) {
15016             continue;
15017         }
15018         TLOGD(WmsLogTag::WMS_KEYBOARD, "isSystemKeyboard: %{public}d, callingSessionId: %{public}d",
15019             keyboardSession->IsSystemKeyboard(), keyboardSession->GetCallingSessionId());
15020         if (!keyboardSession->IsSystemKeyboard() &&
15021             static_cast<int32_t>(keyboardSession->GetCallingSessionId()) == persistentId) {
15022             CallingWindowInfo callingWindowInfo(persistentId, sceneSession->GetCallingPid(), displayId, GetUserIdByUid(getuid()));
15023             SessionManagerAgentController::GetInstance().NotifyCallingWindowDisplayChanged(callingWindowInfo);
15024             break;
15025         }
15026     }
15027     return;
15028 }
15029 
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)15030 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
15031     int32_t x, int32_t y, std::vector<int32_t>& windowIds)
15032 {
15033     TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
15034           displayId, windowNumber, x, y);
15035     if (displayId == DISPLAY_ID_INVALID) {
15036         TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
15037         return WMError::WM_ERROR_INVALID_PARAM;
15038     }
15039     bool findAllWindow = windowNumber <= 0;
15040     std::string callerBundleName = SessionPermission::GetCallingBundleName();
15041     ChangeWindowRectYInVirtualDisplay(displayId, y);
15042     bool checkPoint = (x >= 0 && y >= 0);
15043     auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
15044         findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
15045         if (session == nullptr) {
15046             return false;
15047         }
15048         if (!findAllWindow && windowNumber == 0) {
15049             return true;
15050         }
15051         bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
15052         bool isSameDisplayId = session->GetSessionProperty()->GetDisplayId() == displayId;
15053         bool isRsVisible = session->GetRSVisible();
15054         WSRect windowRect = session->GetSessionRect();
15055         bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
15056         TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
15057                " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
15058                session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
15059                session->GetSessionProperty()->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
15060         if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
15061             return false;
15062         }
15063         windowIds.emplace_back(session->GetPersistentId());
15064         windowNumber--;
15065         return false;
15066     };
15067     return taskScheduler_->PostSyncTask([this, func = std::move(func)] {
15068         TraverseSessionTree(func, true);
15069         return WMError::WM_OK;
15070     }, __func__);
15071 }
15072 
ChangeWindowRectYInVirtualDisplay(DisplayId & displayId,int32_t & y)15073 void SceneSessionManager::ChangeWindowRectYInVirtualDisplay(DisplayId& displayId, int32_t& y)
15074 {
15075     if (displayId != VIRTUAL_DISPLAY_ID) {
15076         TLOGI(WmsLogTag::WMS_LAYOUT_PC, "This is not VIRTUAL_DISPLAY_ID");
15077         return;
15078     }
15079     auto defaultScreenDisplay = DisplayManager::GetInstance().GetDisplayById(DEFAULT_DISPLAY_ID);
15080     if (defaultScreenDisplay == nullptr) {
15081         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get display object failed of defaultScreenDisplay");
15082         return;
15083     }
15084     auto defaultScreenDisplayInfo = defaultScreenDisplay->GetDisplayInfo();
15085     if (defaultScreenDisplayInfo == nullptr) {
15086         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "get display info failed of defaultScreenDisplay");
15087         return;
15088     }
15089     int32_t defaultScreenPhysicalHeight = defaultScreenDisplayInfo->GetPhysicalHeight();
15090     auto screenDisplay = DisplayManager::GetInstance().GetDisplayById(displayId);
15091     int32_t screenHightByDisplayId = defaultScreenPhysicalHeight;
15092     if (screenDisplay != nullptr) {
15093         if (screenDisplay->GetDisplayInfo() != nullptr) {
15094             screenHightByDisplayId = screenDisplay->GetDisplayInfo()->GetHeight();
15095         }
15096     }
15097     TLOGI(WmsLogTag::WMS_LAYOUT_PC, "defaultScreenPhysicalHeight %{public}d screenHightByDisplayId %{public}d",
15098         defaultScreenPhysicalHeight, screenHightByDisplayId);
15099     if (displayId == VIRTUAL_DISPLAY_ID) {
15100         displayId = DEFAULT_DISPLAY_ID;
15101         y = y + defaultScreenPhysicalHeight - screenHightByDisplayId;
15102     }
15103 }
15104 
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const15105 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
15106 {
15107     if (!infos.empty()) {
15108         TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
15109         return WMError::WM_ERROR_INVALID_PARAM;
15110     }
15111     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15112         TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
15113         return WMError::WM_ERROR_INVALID_PERMISSION;
15114     }
15115     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15116     for (const auto& iter : sceneSessionMap_) {
15117         auto& session = iter.second;
15118         if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
15119             continue;
15120         }
15121         MainWindowInfo info;
15122         auto abilityInfo = session->GetSessionInfo().abilityInfo;
15123         info.pid_ = session->GetCallingPid();
15124         info.bundleName_ = session->GetSessionInfo().bundleName_;
15125         info.persistentId_ = session->GetPersistentId();
15126         if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
15127             TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
15128             info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
15129             infos.push_back(info);
15130         } else if (abilityInfo != nullptr) {
15131             info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
15132             infos.push_back(info);
15133             TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
15134                 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
15135                 info.bundleName_.c_str(), info.bundleType_);
15136         }
15137     }
15138     return WMError::WM_OK;
15139 }
15140 
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)15141 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
15142     std::vector<int32_t>& clearFailedIds)
15143 {
15144     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15145         TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
15146         return WMError::WM_ERROR_INVALID_PERMISSION;
15147     }
15148     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
15149         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
15150         return WMError::WM_ERROR_INVALID_PERMISSION;
15151     }
15152     clearFailedIds.clear();
15153     for (const auto persistentId : persistentIds) {
15154         auto sceneSession = GetSceneSession(persistentId);
15155         if (sceneSession == nullptr) {
15156             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
15157             clearFailedIds.push_back(persistentId);
15158             continue;
15159         }
15160         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
15161             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
15162             clearFailedIds.push_back(persistentId);
15163             continue;
15164         }
15165         sceneSession->Clear();
15166         TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
15167     }
15168     return WMError::WM_OK;
15169 }
15170 
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)15171 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
15172     bool enable)
15173 {
15174     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
15175         width, height, density, enable);
15176 
15177     DMHookInfo dmHookInfo;
15178     dmHookInfo.width_ = width;
15179     dmHookInfo.height_ = height;
15180     dmHookInfo.density_ = density;
15181     dmHookInfo.rotation_ = 0;
15182     dmHookInfo.enableHookRotation_ = false;
15183     dmHookInfo.displayOrientation_ = 0;
15184     dmHookInfo.enableHookDisplayOrientation_ = false;
15185     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
15186     return WMError::WM_OK;
15187 }
15188 
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)15189 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
15190 {
15191     TLOGI(WmsLogTag::WMS_COMPAT, "hookInfo: [%{public}s], enable: %{public}d", hookInfo.ToString().c_str(), enable);
15192     if (enable && (uid <= 0 || hookInfo.width_ <= 0 || hookInfo.height_ <= 0 || hookInfo.density_ <= 0)) {
15193         TLOGE(WmsLogTag::WMS_COMPAT, "App hookInfo param error.");
15194         return WMError::WM_ERROR_INVALID_PARAM;
15195     }
15196     DMHookInfo dmHookInfo;
15197     dmHookInfo.width_ = hookInfo.width_;
15198     dmHookInfo.height_ = hookInfo.height_;
15199     dmHookInfo.density_ = hookInfo.density_;
15200     dmHookInfo.rotation_ = hookInfo.rotation_;
15201     dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
15202     dmHookInfo.displayOrientation_ = hookInfo.displayOrientation_;
15203     dmHookInfo.enableHookDisplayOrientation_ = hookInfo.enableHookDisplayOrientation_;
15204     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
15205     return WMError::WM_OK;
15206 }
15207 
UpdateAppHookWindowInfo(const std::string & bundleName,const HookWindowInfo & hookWindowInfo)15208 WMError SceneSessionManager::UpdateAppHookWindowInfo(const std::string& bundleName,
15209                                                      const HookWindowInfo& hookWindowInfo)
15210 {
15211     if (bundleName.empty()) {
15212         TLOGE(WmsLogTag::WMS_LAYOUT, "Bundle name is empty");
15213         return WMError::WM_ERROR_NULLPTR;
15214     }
15215     if (hookWindowInfo.widthHookRatio < 0.0f) {
15216         TLOGE(WmsLogTag::WMS_LAYOUT, "Invalid hook window parameters: widthHookRatio:%{public}f, "
15217             "bundleName:%{public}s", hookWindowInfo.widthHookRatio, bundleName.c_str());
15218         return WMError::WM_ERROR_INVALID_PARAM;
15219     }
15220     TLOGI(WmsLogTag::WMS_LAYOUT, "bundleName:%{public}s, hookWindowInfo:[%{public}s]", bundleName.c_str(),
15221         hookWindowInfo.ToString().c_str());
15222 
15223     HookWindowInfo preInfo;
15224     {
15225         std::unique_lock lock(appHookWindowInfoMapMutex_);
15226         if (appHookWindowInfoMap_.count(bundleName)) {
15227             preInfo = appHookWindowInfoMap_[bundleName];
15228         } else {
15229             preInfo = {};
15230         }
15231         appHookWindowInfoMap_[bundleName] = hookWindowInfo;
15232     }
15233 
15234     if (preInfo.enableHookWindow != hookWindowInfo.enableHookWindow ||
15235         !MathHelper::NearZero(preInfo.widthHookRatio - hookWindowInfo.widthHookRatio)) {
15236         //Notify the client of the info change
15237         std::shared_lock lock(sceneSessionMapMutex_);
15238         for (const auto& [_, session] : sceneSessionMap_) {
15239             if (session && session->GetSessionInfo().bundleName_ == bundleName) {
15240                 session->NotifyAppHookWindowInfoUpdated();
15241             }
15242         }
15243     }
15244     return WMError::WM_OK;
15245 }
15246 
GetAppHookWindowInfo(const std::string & bundleName)15247 HookWindowInfo SceneSessionManager::GetAppHookWindowInfo(const std::string& bundleName)
15248 {
15249     if (bundleName.empty()) {
15250         TLOGW(WmsLogTag::WMS_LAYOUT, "Empty bundle name requested");
15251         return {};
15252     }
15253     std::shared_lock lock(appHookWindowInfoMapMutex_);
15254     const auto& it = appHookWindowInfoMap_.find(bundleName);
15255     if (it == appHookWindowInfoMap_.end()) {
15256         TLOGD(WmsLogTag::WMS_LAYOUT, "app: %{public}s, hookWindowInfo not find", bundleName.c_str());
15257         return {};
15258     }
15259     return it->second;
15260 }
15261 
UpdateAppHookWindowInfoWhenSwitchFreeMultiWindow(bool isOpenFreeMultiWindow)15262 void SceneSessionManager::UpdateAppHookWindowInfoWhenSwitchFreeMultiWindow(bool isOpenFreeMultiWindow)
15263 {
15264     std::unordered_set<std::string> bundleNames;
15265     {
15266         std::unique_lock lock(appHookWindowInfoMapMutex_);
15267         for (auto& [bundleName, hookWindowInfo] : appHookWindowInfoMap_) {
15268             hookWindowInfo.enableHookWindow = !isOpenFreeMultiWindow;
15269             bundleNames.insert(bundleName);
15270         }
15271     }
15272     {
15273         std::shared_lock lock(sceneSessionMapMutex_);
15274         for (const auto& [_, session] : sceneSessionMap_) {
15275             if (session && bundleNames.count(session->GetSessionInfo().bundleName_)) {
15276                 session->NotifyAppHookWindowInfoUpdated();
15277             }
15278         }
15279     }
15280 }
15281 
NotifyHookOrientationChange(int32_t persistentId)15282 WMError SceneSessionManager::NotifyHookOrientationChange(int32_t persistentId)
15283 {
15284     auto sceneSession = GetSceneSession(persistentId);
15285     if (sceneSession == nullptr) {
15286         TLOGE(WmsLogTag::WMS_COMPAT, "session id:%{public}d is not found", persistentId);
15287         return WMError::WM_ERROR_INVALID_PARAM;
15288     }
15289     sceneSession->UpdateOrientation();
15290     return WMError::WM_OK;
15291 }
15292 
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)15293 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
15294 {
15295     SceneSessionManager::GetInstance().SetDelayRemoveSnapshot(true);
15296     SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
15297 }
15298 
SetDelayRemoveSnapshot(bool delayRemoveSnapshot)15299 void SceneSessionManager::SetDelayRemoveSnapshot(bool delayRemoveSnapshot)
15300 {
15301     TLOGD(WmsLogTag::WMS_PATTERN, "delayRemoveSnapshot %{public}d", delayRemoveSnapshot);
15302     delayRemoveSnapshot_ = delayRemoveSnapshot;
15303 }
15304 
GetDelayRemoveSnapshot() const15305 bool SceneSessionManager::GetDelayRemoveSnapshot() const
15306 {
15307     return delayRemoveSnapshot_;
15308 }
15309 
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)15310 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
15311 {
15312     ScreenFoldData screenFoldData;
15313     WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
15314     if (ret != WMError::WM_OK) {
15315         return ret;
15316     }
15317     return CheckAndReportScreenFoldStatus(screenFoldData);
15318 }
15319 
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)15320 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
15321     ScreenFoldData& screenFoldData)
15322 {
15323     if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
15324         TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
15325         return WMError::WM_DO_NOTHING;
15326     }
15327 
15328     screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
15329     screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
15330     screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
15331     screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
15332     screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
15333     if (!screenFoldData.GetTypeCThermalWithUtil()) {
15334         TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
15335         return WMError::WM_DO_NOTHING;
15336     }
15337     AppExecFwk::ElementName element = {};
15338     WSError ret = GetFocusSessionElement(element);
15339     auto sceneSession = GetSceneSession(windowFocusController_->GetFocusedSessionId(DEFAULT_DISPLAY_ID));
15340     if (sceneSession == nullptr || ret != WSError::WS_OK) {
15341         TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
15342         return WMError::WM_DO_NOTHING;
15343     }
15344     screenFoldData.SetFocusedPkgName(element.GetURI());
15345     return WMError::WM_OK;
15346 }
15347 
CheckAndReportScreenFoldStatus(ScreenFoldData & data)15348 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
15349 {
15350     static ScreenFoldData lastScreenHalfFoldData;
15351     if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
15352         lastScreenHalfFoldData = data;
15353         return WMError::WM_DO_NOTHING;
15354     }
15355     WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
15356     if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
15357         if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
15358             lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
15359         } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
15360             // if stay at half-fold less than 15s, combine this change with last
15361             data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
15362             data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
15363             data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
15364         }
15365         lastScreenHalfFoldData.SetInvalid();
15366     }
15367     WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
15368     return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
15369         currentScreenFoldStatusReportRet;
15370 }
15371 
15372 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)15373 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
15374 {
15375     if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
15376         return WMError::WM_DO_NOTHING;
15377     }
15378 
15379     int32_t ret = HiSysEventWrite(
15380         OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
15381         "FOLDSCREEN_STATE_CHANGE",
15382         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
15383         "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
15384         "LASTFOLDSTATE", data.currentScreenFoldStatus_,
15385         "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
15386         "STATE", -1,
15387         "TIME", data.currentScreenFoldStatusDuration_,
15388         "ROTATION", data.screenRotation_,
15389         "PACKAGE", data.focusedPackageName_,
15390         "ANGLE", data.postureAngle_,
15391         "TYPECTHERMAL", data.typeCThermal_,
15392         "SCREENTHERMAL", -1,
15393         "SCANGLE", -1,
15394         "ISTENT", -1);
15395     if (ret != 0) {
15396         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
15397         return WMError::WM_DO_NOTHING;
15398     }
15399     return WMError::WM_OK;
15400 }
15401 
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userId)15402 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userId)
15403 {
15404     if (currentUserId_ != static_cast<int32_t>(userId)) {
15405         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
15406             currentUserId_.load(), userId);
15407         return;
15408     }
15409     if (secExtensionData == nullptr) {
15410         TLOGE(WmsLogTag::WMS_EVENT, "invalid secExtensionData");
15411         return;
15412     }
15413     auto secSurfaceInfoMap = secExtensionData->GetSecData();
15414     auto task = [secSurfaceInfoMap]()-> WSError {
15415         SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
15416         return WSError::WS_OK;
15417     };
15418     taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
15419 }
15420 
RegisterSecSurfaceInfoListener()15421 void SceneSessionManager::RegisterSecSurfaceInfoListener()
15422 {
15423     auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
15424         this->UpdateSecSurfaceInfo(secExtensionData, userid);
15425     };
15426     TLOGI(WmsLogTag::WMS_EVENT, "in");
15427     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
15428         TLOGE(WmsLogTag::WMS_EVENT, "failed");
15429     }
15430 }
15431 
UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,uint64_t userId)15432 void SceneSessionManager::UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,
15433     uint64_t userId)
15434 {
15435     if (currentUserId_ != static_cast<int32_t>(userId)) {
15436         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
15437             currentUserId_.load(), userId);
15438         return;
15439     }
15440     if (constrainedModalUIExtData == nullptr) {
15441         TLOGE(WmsLogTag::WMS_EVENT, "invalid constrainedModalUIExtData");
15442         return;
15443     }
15444     auto constrainedModalUIExtInfoMap = constrainedModalUIExtData->GetSecData();
15445     auto task = [constrainedModalUIExtInfoMap]()-> WSError {
15446         SceneInputManager::GetInstance().UpdateConstrainedModalUIExtInfo(constrainedModalUIExtInfoMap);
15447         return WSError::WS_OK;
15448     };
15449     taskScheduler_->PostAsyncTask(task, "UpdateConstrainedModalUIExtInfo");
15450 }
15451 
RegisterConstrainedModalUIExtInfoListener()15452 void SceneSessionManager::RegisterConstrainedModalUIExtInfoListener()
15453 {
15454     auto callBack = [this](std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData, uint64_t userid) {
15455         this->UpdateConstrainedModalUIExtInfo(constrainedModalUIExtData, userid);
15456     };
15457     TLOGI(WmsLogTag::WMS_EVENT, "in");
15458     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack, true) != WM_OK) {
15459         TLOGE(WmsLogTag::WMS_EVENT, "failed");
15460     }
15461 }
15462 
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)15463 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
15464     const AppForceLandscapeConfig& config)
15465 {
15466     if (bundleName.empty()) {
15467         TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
15468         return WSError::WS_ERROR_NULLPTR;
15469     }
15470     AppForceLandscapeConfig preConfig;
15471     {
15472         std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
15473         if (appForceLandscapeMap_.count(bundleName)) {
15474             preConfig = appForceLandscapeMap_[bundleName];
15475         } else {
15476             preConfig = {};
15477         }
15478         appForceLandscapeMap_[bundleName] = config;
15479     }
15480     TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s, supportSplit: %{public}d, "
15481         "arkUIOptions: %{public}s", bundleName.c_str(), config.mode_, config.homePage_.c_str(), config.supportSplit_,
15482         config.arkUIOptions_.c_str());
15483 
15484     if (preConfig.mode_ == FORCE_SPLIT_MODE || config.mode_ == FORCE_SPLIT_MODE ||
15485         preConfig.mode_ == NAV_FORCE_SPLIT_MODE || config.mode_ == NAV_FORCE_SPLIT_MODE) {
15486         //Notify the client of the mode change
15487         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15488         for (const auto& iter : sceneSessionMap_) {
15489             auto& session = iter.second;
15490             if (session && session->GetSessionInfo().bundleName_ == bundleName) {
15491                 session->NotifyAppForceLandscapeConfigUpdated();
15492             }
15493         }
15494     }
15495     return WSError::WS_OK;
15496 }
15497 
GetAppForceLandscapeConfig(const std::string & bundleName)15498 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
15499 {
15500     if (bundleName.empty()) {
15501         return {};
15502     }
15503     std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
15504     if (appForceLandscapeMap_.empty() ||
15505         appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
15506         TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
15507         return {};
15508     }
15509     return appForceLandscapeMap_[bundleName];
15510 }
15511 
TerminateSessionByPersistentId(int32_t persistentId)15512 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
15513 {
15514     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
15515         TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
15516         return WMError::WM_ERROR_INVALID_PERMISSION;
15517     }
15518     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
15519         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
15520         return WMError::WM_ERROR_NOT_SYSTEM_APP;
15521     }
15522     auto sceneSession = GetSceneSession(persistentId);
15523     if (sceneSession == nullptr) {
15524         TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
15525         return WMError::WM_ERROR_INVALID_PARAM;
15526     }
15527     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
15528         TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
15529         return WMError::WM_ERROR_INVALID_PARAM;
15530     }
15531     sceneSession->Clear(true);
15532     TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
15533     return WMError::WM_OK;
15534 }
15535 
PendingSessionToBackgroundByPersistentId(const int32_t persistentId,bool shouldBackToCaller)15536 WSError SceneSessionManager::PendingSessionToBackgroundByPersistentId(const int32_t persistentId,
15537     bool shouldBackToCaller)
15538 {
15539     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
15540         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
15541         return WSError::WS_ERROR_INVALID_PERMISSION;
15542     }
15543     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
15544     if (!SessionPermission::VerifyPermissionByCallerToken(callerToken,
15545             PermissionConstants::PERMISSION_MANAGE_MISSION)) {
15546         TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, no manage misson permission");
15547         return WSError::WS_ERROR_INVALID_PERMISSION;
15548     }
15549     return taskScheduler_->PostSyncTask([this, persistentId, shouldBackToCaller] {
15550         auto sceneSession = GetSceneSession(persistentId);
15551         if (sceneSession == nullptr) {
15552             TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
15553             return WSError::WS_ERROR_INVALID_PARAM;
15554         }
15555         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
15556             TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
15557             return WSError::WS_ERROR_INVALID_OPERATION;
15558         }
15559         return sceneSession->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
15560     }, __func__);
15561 }
15562 
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)15563 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
15564 {
15565     rootSceneProcessBackEventFunc_ = processBackEventFunc;
15566     TLOGI(WmsLogTag::WMS_EVENT, "end");
15567 }
15568 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)15569 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
15570     const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
15571 {
15572     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15573         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
15574         return WMError::WM_ERROR_INVALID_PERMISSION;
15575     }
15576 
15577     surfaceNodeIds.clear();
15578     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
15579     for (auto persistentId : persistentIds) {
15580         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "convert wid:%{public}d", persistentId);
15581         auto sceneSession = GetSceneSession(persistentId);
15582         if (sceneSession == nullptr) {
15583             continue;
15584         }
15585         auto callingPid = sceneSession->GetCallingPid();
15586         auto surfaceNode = sceneSession->GetSurfaceNode();
15587         if (surfaceNode != nullptr && callingPid == pid) {
15588             surfaceNodeIds.push_back(surfaceNode->GetId());
15589             auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
15590             if (leashWinSurfaceNode != nullptr) {
15591                 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
15592                 surfaceNodeIds.push_back(persistentId);
15593             }
15594         }
15595     }
15596 
15597     return WMError::WM_OK;
15598 }
15599 
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)15600 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
15601 {
15602     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
15603     auto task = [this, func] {
15604         closeTargetFloatWindowFunc_ = func;
15605     };
15606     taskScheduler_->PostTask(task, __func__);
15607 }
15608 
CloseTargetFloatWindow(const std::string & bundleName)15609 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
15610 {
15611     if (!SessionPermission::IsSystemServiceCalling(false)) {
15612         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
15613         return WMError::WM_ERROR_INVALID_PERMISSION;
15614     }
15615     auto task = [this, bundleName] {
15616         if (closeTargetFloatWindowFunc_) {
15617             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
15618             closeTargetFloatWindowFunc_(bundleName);
15619         }
15620     };
15621     taskScheduler_->PostTask(task, __func__);
15622     return WMError::WM_OK;
15623 }
15624 
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)15625 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
15626 {
15627     SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
15628 }
15629 
CloseTargetPiPWindow(const std::string & bundleName)15630 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
15631 {
15632     if (!SessionPermission::IsSystemServiceCalling(false)) {
15633         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
15634         return WMError::WM_ERROR_INVALID_PERMISSION;
15635     }
15636     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15637     for (const auto& iter : sceneSessionMap_) {
15638         auto& session = iter.second;
15639         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
15640             session->GetSessionInfo().bundleName_ == bundleName) {
15641             session->NotifyCloseExistPipWindow();
15642             break;
15643         }
15644     }
15645     return WMError::WM_OK;
15646 }
15647 
GetCurrentPiPWindowInfo(std::string & bundleName)15648 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
15649 {
15650     if (!SessionPermission::IsSystemServiceCalling(false)) {
15651         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
15652         return WMError::WM_ERROR_INVALID_PERMISSION;
15653     }
15654     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15655     for (const auto& iter : sceneSessionMap_) {
15656         auto& session = iter.second;
15657         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
15658             bundleName = session->GetSessionInfo().bundleName_;
15659             return WMError::WM_OK;
15660         }
15661     }
15662     TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
15663     return WMError::WM_OK;
15664 }
15665 
RefreshPcZOrderList(uint32_t startZOrder,std::vector<int32_t> && persistentIds)15666 void SceneSessionManager::RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)
15667 {
15668     const char* const where = __func__;
15669     auto task = [this, startZOrder, persistentIds = std::move(persistentIds), where] {
15670         std::ostringstream oss;
15671         oss << "[";
15672         for (size_t i = 0; i < persistentIds.size(); i++) {
15673             int32_t persistentId = persistentIds[i];
15674             oss << persistentId;
15675             if (i < persistentIds.size() - 1) {
15676                 oss << ",";
15677             }
15678             auto sceneSession = GetSceneSession(persistentId);
15679             if (sceneSession == nullptr) {
15680                 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr persistentId=%{public}d", persistentId);
15681                 continue;
15682             }
15683             if (i > UINT32_MAX - startZOrder) {
15684                 TLOGNE(WmsLogTag::WMS_LAYOUT, "Z order overflow, stop refresh");
15685                 break;
15686             }
15687             sceneSession->SetPcScenePanel(true);
15688             sceneSession->UpdatePCZOrderAndMarkDirty(i + startZOrder);
15689         }
15690         oss << "]";
15691         TLOGND(WmsLogTag::WMS_LAYOUT, "%{public}s: %{public}s", where, oss.str().c_str());
15692         return WSError::WS_OK;
15693     };
15694     taskScheduler_->PostTask(task, __func__);
15695 }
15696 
SkipSnapshotForAppProcess(int32_t pid,bool skip)15697 WMError SceneSessionManager::SkipSnapshotForAppProcess(int32_t pid, bool skip)
15698 {
15699     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15700         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
15701         return WMError::WM_ERROR_INVALID_PERMISSION;
15702     }
15703     if (pid < 0) {
15704         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "invalid pid!");
15705         return WMError::WM_ERROR_INVALID_PARAM;
15706     }
15707     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d, skip:%{public}u", pid, skip);
15708     auto task = [this, pid, skip]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
15709         if (skip) {
15710             snapshotSkipPidSet_.insert(pid);
15711         } else {
15712             snapshotSkipPidSet_.erase(pid);
15713         }
15714         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15715         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
15716             if (sceneSession == nullptr) {
15717                 continue;
15718             }
15719             if (pid == sceneSession->GetCallingPid()) {
15720                 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "send rs set snapshot skip, persistentId:%{public}d, skip:%{public}u",
15721                     persistentId, skip);
15722                 sceneSession->SetSnapshotSkip(skip);
15723             }
15724         }
15725     };
15726     taskScheduler_->PostTask(task, "SkipSnapshotForAppProcess");
15727     return WMError::WM_OK;
15728 }
15729 
RemoveProcessSnapshotSkip(int32_t pid)15730 void SceneSessionManager::RemoveProcessSnapshotSkip(int32_t pid)
15731 {
15732     if (snapshotSkipPidSet_.erase(pid) != 0) {
15733         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from snapshot skip pid set. pid:%{public}d", pid);
15734     }
15735 }
15736 
SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession> & sceneSession)15737 void SceneSessionManager::SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)
15738 {
15739     auto callingPid = sceneSession->GetCallingPid();
15740     if (snapshotSkipPidSet_.find(callingPid) != snapshotSkipPidSet_.end()) {
15741         sceneSession->SetSnapshotSkip(true);
15742     }
15743 }
15744 
SkipSnapshotByUserIdAndBundleNames(int32_t userId,const std::vector<std::string> & bundleNameList)15745 WMError SceneSessionManager::SkipSnapshotByUserIdAndBundleNames(int32_t userId,
15746     const std::vector<std::string>& bundleNameList)
15747 {
15748     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15749         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "The caller has no permission granted.");
15750         return WMError::WM_ERROR_INVALID_PERMISSION;
15751     }
15752     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "userId:%{public}d", userId);
15753     auto task = [this, userId, bundleNameList]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
15754         snapshotSkipBundleNameSet_.clear();
15755         for (auto& bundleName : bundleNameList) {
15756             snapshotSkipBundleNameSet_.insert(std::move(bundleName));
15757         }
15758         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15759         for (const auto& [_, sceneSession] : sceneSessionMap_) {
15760             if (sceneSession == nullptr) {
15761                 continue;
15762             }
15763             const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
15764             if (snapshotSkipBundleNameSet_.find(bundleName) != snapshotSkipBundleNameSet_.end()) {
15765                 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
15766                     bundleName.c_str());
15767                 sceneSession->SetSnapshotSkip(true);
15768                 continue;
15769             }
15770             sceneSession->SetSnapshotSkip(false);
15771         }
15772     };
15773     taskScheduler_->PostTask(task, __func__);
15774     return WMError::WM_OK;
15775 }
15776 
SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession> & sceneSession)15777 void SceneSessionManager::SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)
15778 {
15779     const std::string& name = sceneSession->GetSessionInfo().bundleName_;
15780     if (snapshotSkipBundleNameSet_.find(name) != snapshotSkipBundleNameSet_.end()) {
15781         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "set RS snapshot skip true, name:%{public}s",
15782             name.c_str());
15783         sceneSession->SetSnapshotSkip(true);
15784     }
15785 }
15786 
SetProcessWatermark(int32_t pid,const std::string & watermarkName,bool isEnabled)15787 WMError SceneSessionManager::SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)
15788 {
15789     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15790         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
15791         return WMError::WM_ERROR_INVALID_PERMISSION;
15792     }
15793     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "pid:%{public}d, watermarkName:%{public}s, isEnabled:%{public}u",
15794         pid, watermarkName.c_str(), isEnabled);
15795     if (isEnabled && watermarkName.empty()) {
15796         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "watermarkName is empty!");
15797         return WMError::WM_ERROR_INVALID_PARAM;
15798     }
15799     auto task = [this, pid, watermarkName, isEnabled] {
15800         if (isEnabled) {
15801             processWatermarkPidMap_.insert_or_assign(pid, watermarkName);
15802         } else {
15803             processWatermarkPidMap_.erase(pid);
15804         }
15805 
15806         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15807         for (const auto& [_, sceneSession] : sceneSessionMap_) {
15808             if (sceneSession == nullptr) {
15809                 continue;
15810             }
15811             if (pid == sceneSession->GetCallingPid()) {
15812                 sceneSession->SetWatermarkEnabled(watermarkName, isEnabled);
15813             }
15814         }
15815     };
15816     taskScheduler_->PostTask(task, __func__);
15817     return WMError::WM_OK;
15818 }
15819 
SetSessionWatermarkForAppProcess(const sptr<SceneSession> & sceneSession)15820 bool SceneSessionManager::SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)
15821 {
15822     if (auto iter = processWatermarkPidMap_.find(sceneSession->GetCallingPid());
15823         iter != processWatermarkPidMap_.end()) {
15824         sceneSession->SetWatermarkEnabled(iter->second, true);
15825         return true;
15826     }
15827     return false;
15828 }
15829 
RemoveProcessWatermarkPid(int32_t pid)15830 void SceneSessionManager::RemoveProcessWatermarkPid(int32_t pid)
15831 {
15832     if (processWatermarkPidMap_.find(pid) != processWatermarkPidMap_.end()) {
15833         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "process died, delete pid from watermark pid map. pid:%{public}d", pid);
15834         processWatermarkPidMap_.erase(pid);
15835     }
15836 }
15837 
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)15838 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
15839 {
15840     if (!SessionPermission::IsSystemServiceCalling()) {
15841         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
15842         return WMError::WM_ERROR_INVALID_PERMISSION;
15843     }
15844     const char* const where = __func__;
15845     auto task = [this, persistentId, &hostWindowId, where]() {
15846         hostWindowId = INVALID_WINDOW_ID;
15847         sptr<Session> session = GetSceneSession(persistentId);
15848         while (session && SessionHelper::IsSubWindow(session->GetWindowType())) {
15849             session = session->GetParentSession();
15850         }
15851         if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
15852             hostWindowId = session->GetPersistentId();
15853         }
15854         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
15855             where, persistentId, hostWindowId);
15856         return WMError::WM_OK;
15857     };
15858     return taskScheduler_->PostSyncTask(task, where);
15859 }
15860 
GetMaxInstanceCount(const std::string & bundleName)15861 uint32_t SceneSessionManager::GetMaxInstanceCount(const std::string& bundleName)
15862 {
15863     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
15864         return MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
15865     } else {
15866         return 0u;
15867     }
15868 }
15869 
GetInstanceCount(const std::string & bundleName)15870 uint32_t SceneSessionManager::GetInstanceCount(const std::string& bundleName)
15871 {
15872     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
15873         return MultiInstanceManager::GetInstance().GetInstanceCount(bundleName);
15874     } else {
15875         return 0u;
15876     }
15877 }
15878 
GetLastInstanceKey(const std::string & bundleName)15879 std::string SceneSessionManager::GetLastInstanceKey(const std::string& bundleName)
15880 {
15881     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
15882         return MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
15883     } else {
15884         return "";
15885     }
15886 }
15887 
RefreshAppInfo(const std::string & bundleName)15888 void SceneSessionManager::RefreshAppInfo(const std::string& bundleName)
15889 {
15890     MultiInstanceManager::GetInstance().RefreshAppInfo(bundleName);
15891     AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
15892 }
15893 
UpdateScreenLockStatusForApp(const std::string & bundleName,bool isRelease)15894 WMError SceneSessionManager::UpdateScreenLockStatusForApp(const std::string& bundleName, bool isRelease)
15895 {
15896     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
15897         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
15898         return WMError::WM_ERROR_INVALID_PERMISSION;
15899     }
15900 #ifdef POWER_MANAGER_ENABLE
15901     if (isRelease) {
15902         return ReleaseScreenLockForApp(bundleName);
15903     } else {
15904         return RelockScreenLockForApp(bundleName);
15905     }
15906 #else
15907     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Can not find the sub system of PowerMgr");
15908     return WMError::WM_OK;
15909 #endif
15910 }
15911 
ReleaseScreenLockForApp(const std::string & bundleName)15912 WMError SceneSessionManager::ReleaseScreenLockForApp(const std::string& bundleName)
15913 {
15914     std::vector<sptr<SceneSession>> sessionsToReleaseScreenLock;
15915     GetAllSessionsToReleaseScreenLock(sessionsToReleaseScreenLock, bundleName);
15916     auto task = [this, bundleName, sessionsToReleaseScreenLock] {
15917         for (const auto& sceneSession : sessionsToReleaseScreenLock) {
15918             if (sceneSession->keepScreenLock_ == nullptr || !sceneSession->keepScreenLock_->IsUsed()) {
15919                 continue;
15920             }
15921             auto res = sceneSession->keepScreenLock_->UnLock();
15922             if (res != ERR_OK) {
15923                 TLOGNE(WmsLogTag::WMS_ATTRIBUTE,
15924                     "release screenlock failed, window:[%{public}d, %{public}s], err:%{public}d",
15925                     sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str(), res);
15926                 continue;
15927             }
15928             auto [iter, emplaced] = releasedScreenLockMap_.try_emplace(bundleName, std::unordered_set<int32_t>{});
15929             iter->second.insert(sceneSession->GetPersistentId());
15930             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "release screenlock success, window:[%{public}d, %{public}s]",
15931                 sceneSession->GetPersistentId(), sceneSession->GetWindowName().c_str());
15932         }
15933         return WMError::WM_OK;
15934     };
15935     return taskScheduler_->PostSyncTask(task, __func__);
15936 }
15937 
GetAllSessionsToReleaseScreenLock(std::vector<sptr<SceneSession>> & sessionsToReleaseScreenLock,const std::string & bundleName)15938 void SceneSessionManager::GetAllSessionsToReleaseScreenLock(
15939     std::vector<sptr<SceneSession>>& sessionsToReleaseScreenLock, const std::string& bundleName) {
15940     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
15941     for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
15942         if (sceneSession->GetSessionInfo().bundleName_ == bundleName && sceneSession->keepScreenLock_ != nullptr) {
15943             sessionsToReleaseScreenLock.push_back(sceneSession);
15944         }
15945     }
15946 }
15947 
RelockScreenLockForApp(const std::string & bundleName)15948 WMError SceneSessionManager::RelockScreenLockForApp(const std::string& bundleName)
15949 {
15950     auto task = [this, bundleName] {
15951         auto iter = releasedScreenLockMap_.find(bundleName);
15952         if (iter == releasedScreenLockMap_.end()) {
15953             TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s: not found in map", bundleName.c_str());
15954             return WMError::WM_ERROR_INVALID_OPERATION;
15955         }
15956         const auto& persistentIds = iter->second;
15957         for (const int32_t persistentId : persistentIds) {
15958             sptr<SceneSession> sceneSession = GetSceneSession(static_cast<int32_t>(persistentId));
15959             if (sceneSession == nullptr) {
15960                 continue;
15961             }
15962             auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
15963             auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(
15964                 sceneSession->GetScreenId());
15965             if (screenSession) {
15966                 sourceMode = screenSession->GetSourceMode();
15967             }
15968             if (sceneSession->IsKeepScreenOn() && IsSessionVisibleForeground(sceneSession) &&
15969                 sourceMode != ScreenSourceMode::SCREEN_UNIQUE && sceneSession->keepScreenLock_ != nullptr) {
15970                 auto res = sceneSession->keepScreenLock_->Lock();
15971                 TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "relock screenlock, window: [%{public}d, %{public}s], res:%{public}d",
15972                     persistentId, sceneSession->GetWindowName().c_str(), res);
15973             }
15974         }
15975         releasedScreenLockMap_.erase(bundleName);
15976         return WMError::WM_OK;
15977     };
15978     return taskScheduler_->PostSyncTask(task, __func__);
15979 }
15980 
IsPcWindow(bool & isPcWindow)15981 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
15982 {
15983     isPcWindow = systemConfig_.IsPcWindow();
15984     return WMError::WM_OK;
15985 }
15986 
IsFreeMultiWindow(bool & isFreeMultiWindow)15987 WMError SceneSessionManager::IsFreeMultiWindow(bool& isFreeMultiWindow)
15988 {
15989     isFreeMultiWindow = systemConfig_.freeMultiWindowEnable_;
15990     return WMError::WM_OK;
15991 }
15992 
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)15993 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
15994 {
15995     isPcOrPadFreeMultiWindowMode = (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode());
15996     return WMError::WM_OK;
15997 }
15998 
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)15999 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
16000     std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
16001 {
16002     if (!SessionPermission::IsSystemCalling()) {
16003         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "permission denied!");
16004         return WMError::WM_ERROR_INVALID_PERMISSION;
16005     }
16006 
16007     auto task = [this, windowIds, &windowDisplayIdMap] {
16008         for (const uint64_t windowId : windowIds) {
16009             sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
16010             if (session == nullptr) {
16011                 continue;
16012             }
16013             DisplayId displayId = session->GetSessionProperty()->GetDisplayId();
16014             if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(displayId)) {
16015                 displayId = session->GetClientDisplayId();
16016             }
16017             TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
16018                 windowId, displayId);
16019             windowDisplayIdMap.insert({windowId, displayId});
16020         }
16021         return WMError::WM_OK;
16022     };
16023     return taskScheduler_->PostSyncTask(task, __func__);
16024 }
16025 
IsLastFrameLayoutFinished(bool & isLayoutFinished)16026 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
16027 {
16028     if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
16029         TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
16030         return WSError::WS_ERROR_NULLPTR;
16031     }
16032     isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
16033     return WSError::WS_OK;
16034 }
16035 
IsWindowRectAutoSave(const std::string & key,bool & enabled,int persistentId)16036 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled, int persistentId)
16037 {
16038     return taskScheduler_->PostSyncTask([key, &enabled, persistentId, this] {
16039         auto sceneSession = GetSceneSession(persistentId);
16040         if (sceneSession == nullptr) {
16041             TLOGNE(WmsLogTag::WMS_MAIN, "sceneSession %{public}d is nullptr", persistentId);
16042             return WMError::WM_ERROR_INVALID_SESSION;
16043         }
16044         std::string specifiedKey = key;
16045         if (auto iter = this->isSaveBySpecifiedFlagMap_.find(key);
16046             iter != this->isSaveBySpecifiedFlagMap_.end()) {
16047             if (iter->second) {
16048                 specifiedKey = key + sceneSession->GetSessionInfo().specifiedFlag_;
16049             }
16050         }
16051         TLOGND(WmsLogTag::WMS_MAIN, "windowId: %{public}d, specifiedKey: %{public}s", persistentId, specifiedKey.c_str());
16052         if (auto iter = this->isWindowRectAutoSaveMap_.find(specifiedKey);
16053             iter != this->isWindowRectAutoSaveMap_.end()) {
16054             enabled = iter->second;
16055         } else {
16056             enabled = false;
16057         }
16058         return WMError::WM_OK;
16059     });
16060 
16061 }
16062 
SetImageForRecent(uint32_t imgResourceId,ImageFit imageFit,int32_t persistentId)16063 WMError SceneSessionManager::SetImageForRecent(uint32_t imgResourceId, ImageFit imageFit, int32_t persistentId)
16064 {
16065     auto sceneSession = GetSceneSession(persistentId);
16066     if (sceneSession == nullptr) {
16067         TLOGE(WmsLogTag::WMS_PATTERN, "sceneSession %{public}d is null", persistentId);
16068         return WMError::WM_ERROR_NULLPTR;
16069     }
16070 
16071     if (sceneSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
16072         TLOGE(WmsLogTag::WMS_PATTERN, "sessionState is invalid");
16073         return WMError::WM_ERROR_NULLPTR;
16074     }
16075     auto abilityInfo = sceneSession->GetSessionInfo().abilityInfo;
16076     if (abilityInfo == nullptr) {
16077         TLOGE(WmsLogTag::WMS_PATTERN, "abilityInfo is null");
16078         return WMError::WM_ERROR_NULLPTR;
16079     }
16080     if (!abilityInfo->applicationInfo.isSystemApp) {
16081         TLOGE(WmsLogTag::WMS_PATTERN, "%{public}d is not a systemApp", persistentId);
16082         return WMError::WM_ERROR_NOT_SYSTEM_APP;
16083     }
16084     std::shared_ptr<Media::PixelMap> pixelMap = GetPixelMap(imgResourceId, abilityInfo);
16085     if (!pixelMap) {
16086         TLOGE(WmsLogTag::WMS_PATTERN, "get pixelMap failed");
16087         return WMError::WM_ERROR_NULLPTR;
16088     }
16089     auto scenePersistence = sceneSession->GetScenePersistence();
16090     if (scenePersistence == nullptr) {
16091         TLOGE(WmsLogTag::WMS_PATTERN, "scenePersistence is null");
16092         return WMError::WM_ERROR_NULLPTR;
16093     }
16094     // Decoupling from LRU
16095     sceneSession->SetSaveSnapshotCallback([](){});
16096     sceneSession->SaveSnapshot(true, true, pixelMap);
16097     scenePersistence->SetHasSnapshot(true);
16098     ScenePersistentStorage::Insert("SetImageForRecent_" + std::to_string(persistentId), static_cast<int32_t>(imageFit), ScenePersistentStorageType::MAXIMIZE_STATE);
16099     return WMError::WM_OK;
16100 }
16101 
GetPersistentImageFit(int32_t persistentId,int32_t & imageFit)16102 bool SceneSessionManager::GetPersistentImageFit(int32_t persistentId, int32_t& imageFit)
16103 {
16104     auto persistentImageFit = ScenePersistentStorage::HasKey("SetImageForRecent_" + std::to_string(persistentId),
16105         ScenePersistentStorageType::MAXIMIZE_STATE);
16106     if (persistentImageFit) {
16107         ScenePersistentStorage::Get("SetImageForRecent_" + std::to_string(persistentId),
16108             imageFit, ScenePersistentStorageType::MAXIMIZE_STATE);
16109         return true;
16110     }
16111     return false;
16112 }
16113 
GetPixelMap(uint32_t resourceId,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)16114 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetPixelMap(uint32_t resourceId,
16115     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
16116 {
16117     auto resourceMgr = GetResourceManager(*abilityInfo.get());
16118     if (resourceMgr == nullptr) {
16119         TLOGW(WmsLogTag::WMS_PATTERN, "resource manager is null");
16120         return nullptr;
16121     }
16122 
16123     Media::SourceOptions opts;
16124     uint32_t errorCode = 0;
16125     std::unique_ptr<Media::ImageSource> imageSource;
16126     if (!abilityInfo->hapPath.empty()) {
16127         std::unique_ptr<uint8_t[]> imageOut;
16128         size_t len;
16129         if (resourceMgr->GetMediaDataById(resourceId, len, imageOut) != Global::Resource::RState::SUCCESS) {
16130             return nullptr;
16131         }
16132         imageSource = Media::ImageSource::CreateImageSource(imageOut.get(), len, opts, errorCode);
16133     } else {
16134         std::string imagePath;
16135         if (resourceMgr->GetMediaById(resourceId, imagePath) != Global::Resource::RState::SUCCESS) {
16136             return nullptr;
16137         }
16138         imageSource = Media::ImageSource::CreateImageSource(imagePath, opts, errorCode);
16139     }
16140 
16141     if (errorCode != 0 || imageSource == nullptr) {
16142         TLOGE(WmsLogTag::WMS_PATTERN, "failed id %{private}d err %{public}d", resourceId, errorCode);
16143         return nullptr;
16144     }
16145 
16146     Media::DecodeOptions decodeOpts;
16147     auto pixelMapPtr = imageSource->CreatePixelMap(decodeOpts, errorCode);
16148     if (errorCode != 0) {
16149         TLOGE(WmsLogTag::WMS_PATTERN, "failed id %{private}d err %{public}d", resourceId, errorCode);
16150         return nullptr;
16151     }
16152     return std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
16153 }
16154 
SetIsWindowRectAutoSave(const std::string & key,bool enabled,const std::string & abilityKey,bool isSaveBySpecifiedFlag)16155 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled,
16156     const std::string& abilityKey, bool isSaveBySpecifiedFlag)
16157 {
16158     taskScheduler_->PostSyncTask([key, enabled, abilityKey, isSaveBySpecifiedFlag ,this] {
16159         if (auto iter = this->isSaveBySpecifiedFlagMap_.find(abilityKey);
16160             iter != this->isSaveBySpecifiedFlagMap_.end()) {
16161             if (!isSaveBySpecifiedFlag) {
16162                 this->isSaveBySpecifiedFlagMap_.erase(abilityKey);
16163             } else {
16164                 iter->second = isSaveBySpecifiedFlag;
16165             }
16166         } else {
16167             if (isSaveBySpecifiedFlag) {
16168                 this->isSaveBySpecifiedFlagMap_.insert({abilityKey, isSaveBySpecifiedFlag});
16169             }
16170         }
16171         if (auto iter = this->isWindowRectAutoSaveMap_.find(key);
16172             iter != this->isWindowRectAutoSaveMap_.end()) {
16173             if (!enabled) {
16174                 this->isWindowRectAutoSaveMap_.erase(key);
16175             } else {
16176                 iter->second = enabled;
16177             }
16178         } else {
16179             if (enabled) {
16180                 this->isWindowRectAutoSaveMap_.insert({key, enabled});
16181             }
16182         }
16183         return WMError::WM_OK;
16184     });
16185 }
16186 
MinimizeMainSession(const std::string & bundleName,int32_t appIndex,int32_t userId)16187 WMError SceneSessionManager::MinimizeMainSession(const std::string& bundleName, int32_t appIndex, int32_t userId)
16188 {
16189     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16190         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16191         return WMError::WM_ERROR_INVALID_PERMISSION;
16192     }
16193     if ((currentUserId_ != userId && currentUserId_ != DEFAULT_USERID) ||
16194         (currentUserId_ == DEFAULT_USERID && userId != GetUserIdByUid(getuid()))) {
16195         TLOGW(WmsLogTag::WMS_LIFE, "currentUserId:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
16196             currentUserId_.load(), userId, GetUserIdByUid(getuid()));
16197         return WMError::WM_ERROR_INVALID_OPERATION;
16198     }
16199     const char* const where = __func__;
16200     taskScheduler_->PostAsyncTask([this, bundleName, appIndex, where] {
16201         std::vector<sptr<SceneSession>> mainSessions;
16202         GetMainSessionByBundleNameAndAppIndex(bundleName, appIndex, mainSessions);
16203         if (mainSessions.empty()) {
16204             TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, not found any main session", where);
16205             return;
16206         }
16207         for (const auto& session : mainSessions) {
16208             session->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
16209             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d.", where, session->GetPersistentId());
16210         }
16211     }, __func__);
16212     return WMError::WM_OK;
16213 }
16214 
SetStartWindowBackgroundColor(const std::string & moduleName,const std::string & abilityName,uint32_t color,int32_t uid)16215 WMError SceneSessionManager::SetStartWindowBackgroundColor(
16216     const std::string& moduleName, const std::string& abilityName, uint32_t color, int32_t uid)
16217 {
16218     if (!bundleMgr_) {
16219         TLOGE(WmsLogTag::WMS_PATTERN, "bundleMgr is nullptr");
16220         return WMError::WM_ERROR_NO_MEM;
16221     }
16222     std::string bundleName;
16223     if (!bundleMgr_->GetBundleNameForUid(uid, bundleName)) {
16224         TLOGE(WmsLogTag::WMS_PATTERN, "get bundle name failed");
16225         return WMError::WM_ERROR_NO_MEM;
16226     }
16227     AppExecFwk::AbilityInfo abilityInfo;
16228     if (!bundleMgr_->GetAbilityInfo(bundleName, moduleName, abilityName, abilityInfo)) {
16229         TLOGE(WmsLogTag::WMS_PATTERN, "ability not found %{public}s %{public}s %{public}s",
16230             bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
16231         return WMError::WM_ERROR_NO_MEM;
16232     }
16233     auto key = moduleName + abilityName;
16234     {
16235         std::unique_lock<std::shared_mutex> lock(startingWindowColorFromAppMapMutex_);
16236         auto iter = startingWindowColorFromAppMap_.find(bundleName);
16237         if (iter != startingWindowColorFromAppMap_.end()) {
16238             iter->second[key] = color;
16239         } else {
16240             std::unordered_map<std::string, uint32_t> colorMap({{ key, color}});
16241             startingWindowColorFromAppMap_.emplace(bundleName, colorMap);
16242         }
16243     }
16244     StartingWindowInfo info;
16245     uint32_t updateRes = UpdateCachedColorToAppSet(bundleName, moduleName, abilityName, info);
16246     TLOGI(WmsLogTag::WMS_PATTERN, "success %{public}s %{public}s, %{public}x, %{public}u",
16247         bundleName.c_str(), key.c_str(), color, updateRes);
16248     return WMError::WM_OK;
16249 }
16250 
ShiftAppWindowPointerEvent(int32_t sourcePersistentId,int32_t targetPersistentId,int32_t fingerId)16251 WMError SceneSessionManager::ShiftAppWindowPointerEvent(int32_t sourcePersistentId, int32_t targetPersistentId,
16252                                                         int32_t fingerId)
16253 {
16254     TLOGD(WmsLogTag::WMS_PC, "sourcePersistentId %{public}d targetPersistentId %{public}d",
16255         sourcePersistentId, targetPersistentId);
16256     sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
16257     if (sourceSession == nullptr) {
16258         TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is nullptr", sourcePersistentId);
16259         return WMError::WM_ERROR_INVALID_SESSION;
16260     }
16261     if (sourceSession->GetSessionProperty()->GetPcAppInpadCompatibleMode() &&
16262         !systemConfig_.IsFreeMultiWindowMode()) {
16263         TLOGE(WmsLogTag::WMS_PC, "This is PcAppInPad, not supported");
16264         return WMError::WM_OK;
16265     }
16266     if (!(systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode())) {
16267         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
16268     }
16269     if (sourcePersistentId == targetPersistentId) {
16270         return WMError::WM_ERROR_INVALID_CALLING;
16271     }
16272     if (!WindowHelper::IsAppWindow(sourceSession->GetWindowType())) {
16273         TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is not app window", sourcePersistentId);
16274         return WMError::WM_ERROR_INVALID_CALLING;
16275     }
16276     sptr<SceneSession> targetSession = GetSceneSession(targetPersistentId);
16277     if (targetSession == nullptr) {
16278         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is nullptr", targetPersistentId);
16279         return WMError::WM_ERROR_INVALID_SESSION;
16280     }
16281     if (!WindowHelper::IsAppWindow(targetSession->GetWindowType())) {
16282         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not app window", targetPersistentId);
16283         return WMError::WM_ERROR_INVALID_CALLING;
16284     }
16285     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
16286         TLOGE(WmsLogTag::WMS_PC, "verify bundle failed, source name is %{public}s but target name is %{public}s",
16287             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
16288         return WMError::WM_ERROR_INVALID_CALLING;
16289     }
16290     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
16291         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not same bundle as calling", targetPersistentId);
16292         return WMError::WM_ERROR_INVALID_CALLING;
16293     }
16294     int32_t callingPid = IPCSkeleton::GetCallingPid();
16295     if (callingPid != targetSession->GetCallingPid()) {
16296         TLOGE(WmsLogTag::WMS_PC, "permission denied, not call by the same process");
16297         return WMError::WM_ERROR_INVALID_CALLING;
16298     }
16299     return ShiftAppWindowPointerEventInner(sourcePersistentId, targetPersistentId,
16300         targetSession->GetSessionProperty()->GetDisplayId(), fingerId);
16301 }
16302 
ShiftAppWindowPointerEventInner(int32_t sourceWindowId,int32_t targetWindowId,DisplayId targetDisplayId,int32_t fingerId)16303 WMError SceneSessionManager::ShiftAppWindowPointerEventInner(
16304     int32_t sourceWindowId, int32_t targetWindowId, DisplayId targetDisplayId, int32_t fingerId)
16305 {
16306     return taskScheduler_->PostSyncTask([sourceWindowId, targetWindowId, targetDisplayId, fingerId] {
16307         auto display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
16308     	float vpr = 1.5f; // 1.5f: default virtual pixel ratio
16309     	if (display) {
16310         	vpr = display->GetVirtualPixelRatio();
16311     	}
16312     	int32_t outside = static_cast<int32_t>(HOTZONE_TOUCH * vpr * 2); // double touch hotzone
16313     	MMI::ShiftWindowParam param;
16314     	param.sourceWindowId = sourceWindowId;
16315     	param.targetWindowId = targetWindowId;
16316     	param.x = -outside;
16317     	param.y = -outside;
16318         if (fingerId == INVALID_FINGER_ID) {
16319             param.sourceType = MMI::PointerEvent::SOURCE_TYPE_MOUSE;
16320         } else {
16321             param.sourceType = MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN;
16322             param.fingerId = fingerId;
16323         }
16324         int ret = MMI::InputManager::GetInstance()->ShiftAppPointerEvent(param, true);
16325         TLOGNI(WmsLogTag::WMS_PC, "sourceWindowId %{public}d targetWindowId %{public}d vpr %{public}f ret %{public}d",
16326             param.sourceWindowId, param.targetWindowId, vpr, ret);
16327         return ret == 0 ? WMError::WM_OK : WMError::WM_ERROR_INVALID_CALLING;
16328     }, __func__);
16329 }
16330 
LockSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,bool isLock)16331 WMError SceneSessionManager::LockSessionByAbilityInfo(const AbilityInfoBase& abilityInfo, bool isLock)
16332 {
16333     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16334         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16335         return WMError::WM_ERROR_INVALID_PERMISSION;
16336     }
16337     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
16338         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
16339         return WMError::WM_ERROR_INVALID_PERMISSION;
16340     }
16341     TLOGI(WmsLogTag::WMS_LIFE,
16342         "bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s appIndex:%{public}d isLock:%{public}d",
16343         abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.abilityName.c_str(),
16344         abilityInfo.appIndex, isLock);
16345     if (!abilityInfo.IsValid()) {
16346         TLOGE(WmsLogTag::WMS_LIFE, "abilityInfo not valid");
16347         return WMError::WM_ERROR_INVALID_PARAM;
16348     }
16349     taskScheduler_->PostAsyncTask([this, abilityInfo, isLock, where = __func__] {
16350         std::vector<sptr<SceneSession>> mainSessions;
16351         GetMainSessionByAbilityInfo(abilityInfo, mainSessions);
16352         if (!mainSessions.empty()) {
16353             for (const auto& mainSession : mainSessions) {
16354                 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, set isLockedState true, persistentId:%{public}d",
16355                     where, mainSession->GetPersistentId());
16356                 mainSession->NotifySessionLockStateChange(isLock);
16357             }
16358             if (isLock) {
16359                 return;
16360             }
16361         }
16362         if (isLock) {
16363             if (sessionLockedStateCacheSet_.size() > MAX_LOCK_STATUS_CACHE_SIZE) {
16364                 auto iter = sessionLockedStateCacheSet_.begin();
16365                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, reach max erase begin:%{public}s", where, (*iter).c_str());
16366                 sessionLockedStateCacheSet_.erase(iter);
16367             }
16368             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, update isLockedState into cache set", where);
16369             sessionLockedStateCacheSet_.insert(abilityInfo.ToKeyString());
16370         } else {
16371             sessionLockedStateCacheSet_.erase(abilityInfo.ToKeyString());
16372         }
16373     }, __func__);
16374     return WMError::WM_OK;
16375 }
16376 
ConfigSupportFunctionType(SupportFunctionType funcType)16377 void SceneSessionManager::ConfigSupportFunctionType(SupportFunctionType funcType)
16378 {
16379     systemConfig_.supportFunctionType_ = funcType;
16380 }
16381 
HasFloatingWindowForeground(const sptr<IRemoteObject> & abilityToken,bool & hasOrNot)16382 WMError SceneSessionManager::HasFloatingWindowForeground(const sptr<IRemoteObject>& abilityToken, bool& hasOrNot)
16383 {
16384     if (!abilityToken) {
16385         TLOGE(WmsLogTag::WMS_SYSTEM, "AbilityToken is null");
16386         return WMError::WM_ERROR_NULLPTR;
16387     }
16388     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
16389         TLOGE(WmsLogTag::WMS_SYSTEM, "Permission denied, only for SA");
16390         return WMError::WM_ERROR_INVALID_PERMISSION;
16391     }
16392 
16393     return taskScheduler_->PostSyncTask([this, &abilityToken, &hasOrNot, where = __func__] {
16394         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16395         for (const auto& [_, session] : sceneSessionMap_) {
16396             if (session && session->GetAbilityToken() == abilityToken &&
16397                 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && session->IsSessionForeground()) {
16398                 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s found", where);
16399                 hasOrNot = true;
16400                 return WMError::WM_OK;
16401             }
16402         }
16403         TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s not found", where);
16404         hasOrNot = false;
16405         return WMError::WM_OK;
16406     }, __func__);
16407 }
16408 
GetFbPanelWindowId(uint32_t & windowId)16409 WMError SceneSessionManager::GetFbPanelWindowId(uint32_t& windowId)
16410 {
16411     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16412     for (const auto& iter : sceneSessionMap_) {
16413         auto& session = iter.second;
16414         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FB &&
16415             session->GetWindowName().find(FB_PANEL_NAME) != std::string::npos) {
16416             windowId = static_cast<uint32_t>(session->GetWindowId());
16417             return WMError::WM_OK;
16418         }
16419     }
16420     TLOGW(WmsLogTag::WMS_SYSTEM, "No Fb panel");
16421     return WMError::WM_ERROR_FB_INTERNAL_ERROR;
16422 }
16423 
SetStatusBarAvoidHeight(DisplayId displayId,int32_t height)16424 void SceneSessionManager::SetStatusBarAvoidHeight(DisplayId displayId, int32_t height)
16425 {
16426     const char* const where = __func__;
16427     auto task = [this, where, displayId, height] {
16428         statusBarAvoidHeight_[displayId] = height >= 0 ? height : INVALID_STATUS_BAR_AVOID_HEIGHT;
16429         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s, displayId %{public}" PRIu64 " height %{public}d",
16430             where, displayId, statusBarAvoidHeight_[displayId]);
16431         return WMError::WM_OK;
16432     };
16433     taskScheduler_->PostSyncTask(task, where);
16434 }
16435 
GetStatusBarAvoidHeight(DisplayId displayId,WSRect & barArea)16436 void SceneSessionManager::GetStatusBarAvoidHeight(DisplayId displayId, WSRect& barArea)
16437 {
16438     auto it = statusBarAvoidHeight_.find(displayId);
16439     if (it == statusBarAvoidHeight_.end()) {
16440         return;
16441     }
16442     if (it->second == INVALID_STATUS_BAR_AVOID_HEIGHT) {
16443         return;
16444     }
16445     TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " height %{public}d", displayId, it->second);
16446     barArea.height_ = it->second;
16447 }
16448 
CloneWindow(int32_t fromPersistentId,int32_t toPersistentId,bool needOffScreen)16449 WSError SceneSessionManager::CloneWindow(int32_t fromPersistentId, int32_t toPersistentId, bool needOffScreen)
16450 {
16451     return taskScheduler_->PostSyncTask([this, fromPersistentId, toPersistentId, needOffScreen]() {
16452         auto toSceneSession = GetSceneSession(toPersistentId);
16453         if (toSceneSession == nullptr) {
16454             TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", toPersistentId);
16455             return WSError::WS_ERROR_NULLPTR;
16456         }
16457         NodeId nodeId = INVALID_NODEID;
16458         if (fromPersistentId >= 0) { // if fromPersistentId < 0, excute CloneWindow(0) to cancel cloneWindow
16459             if (auto fromSceneSession = GetSceneSession(fromPersistentId)) {
16460                 if (auto surfaceNode = fromSceneSession->GetSurfaceNode()) {
16461                     nodeId = surfaceNode->GetId();
16462                 }
16463             } else {
16464                 TLOGNE(WmsLogTag::WMS_PC, "Session is nullptr, id: %{public}d", fromPersistentId);
16465                 return WSError::WS_ERROR_NULLPTR;
16466             }
16467         }
16468         toSceneSession->CloneWindow(nodeId, needOffScreen);
16469         TLOGNI(WmsLogTag::WMS_PC, "fromSurfaceId: %{public}" PRIu64, nodeId);
16470         return WSError::WS_OK;
16471     }, __func__);
16472 }
16473 
UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty> & property)16474 DisplayId SceneSessionManager::UpdateSpecificSessionClientDisplayId(const sptr<WindowSessionProperty>& property)
16475 {
16476     auto initClientDisplayId = DEFAULT_DISPLAY_ID;
16477     //  SubWindow
16478     if (auto parentSession = GetSceneSession(property->GetParentPersistentId())) {
16479         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId:%{public}" PRIu64 ", parentClientDisplayId:%{public}" PRIu64
16480             ", isFollowParentWindowDisplayId: %{public}u", property->GetDisplayId(),
16481             parentSession->GetClientDisplayId(), property->IsFollowParentWindowDisplayId());
16482         initClientDisplayId =
16483             property->IsFollowParentWindowDisplayId() ? parentSession->GetClientDisplayId() : property->GetDisplayId();
16484         if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
16485             property->SetDisplayId(DEFAULT_DISPLAY_ID);
16486         }
16487     }
16488     // SystemWindow
16489     if (property->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
16490         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "displayId:%{public}" PRIu64, property->GetDisplayId());
16491         property->SetDisplayId(DEFAULT_DISPLAY_ID);
16492         initClientDisplayId = VIRTUAL_DISPLAY_ID;
16493     }
16494     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winName:%{public}s, type:%{public}u, displayId:%{public}" PRIu64
16495         ", clientDisplayId:%{public}" PRIu64 ", parentId:%{public}d", property->GetWindowName().c_str(),
16496         property->GetWindowType(), property->GetDisplayId(), initClientDisplayId, property->GetParentPersistentId());
16497     return initClientDisplayId;
16498 }
16499 
UpdateSessionDisplayIdBySessionInfo(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)16500 void SceneSessionManager::UpdateSessionDisplayIdBySessionInfo(
16501     sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
16502 {
16503     if (sceneSession->GetScreenId() == VIRTUAL_DISPLAY_ID &&
16504         sceneSession->GetSessionProperty()->GetDisplayId() == VIRTUAL_DISPLAY_ID) {
16505         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s move display %{public}" PRIu64 " from %{public}" PRIu64,
16506             sessionInfo.bundleName_.c_str(), sessionInfo.screenId_, VIRTUAL_DISPLAY_ID);
16507         sceneSession->SetScreenId(sessionInfo.screenId_);
16508         sceneSession->GetSessionProperty()->SetDisplayId(sessionInfo.screenId_);
16509     }
16510 }
16511 
RemoveLifeCycleTaskByPersistentId(int32_t persistentId,const LifeCycleTaskType taskType)16512 void SceneSessionManager::RemoveLifeCycleTaskByPersistentId(int32_t persistentId,
16513     const LifeCycleTaskType taskType)
16514 {
16515     auto sceneSession = GetSceneSession(persistentId);
16516     if (sceneSession == nullptr) {
16517         TLOGE(WmsLogTag::WMS_LIFE, "session:%{public}d is nullptr", persistentId);
16518         return;
16519     }
16520     sceneSession->RemoveLifeCycleTask(taskType);
16521 }
16522 
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<int32_t> & persistentIdList)16523 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
16524     const std::vector<int32_t>& persistentIdList)
16525 {
16526     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16527         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16528         return WMError::WM_ERROR_INVALID_PERMISSION;
16529     }
16530     if (persistentIdList.empty()) {
16531         TLOGE(WmsLogTag::WMS_LIFE, "persistentIdList is empty!");
16532         return WMError::WM_ERROR_INVALID_PARAM;
16533     }
16534     if (listener == nullptr) {
16535         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
16536         return WMError::WM_ERROR_INVALID_PARAM;
16537     }
16538     if (listenerController_->IsListenerMapByIdSizeReachLimit()) {
16539         TLOGW(WmsLogTag::WMS_LIFE, "The number of listeners has reached the upper limit.");
16540         return WMError::WM_ERROR_NO_MEM;
16541     }
16542     return taskScheduler_->PostSyncTask([this, listener, persistentIdList, where = __func__] {
16543         WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, persistentIdList);
16544         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
16545         return ret;
16546     }, __func__);
16547 }
16548 
RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener,const std::vector<std::string> & bundleNameList)16549 WMError SceneSessionManager::RegisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener,
16550     const std::vector<std::string>& bundleNameList)
16551 {
16552     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16553         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16554         return WMError::WM_ERROR_INVALID_PERMISSION;
16555     }
16556     if (listener == nullptr) {
16557         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
16558         return WMError::WM_ERROR_INVALID_PARAM;
16559     }
16560     if (listenerController_->IsListenerMapByBundleSizeReachLimit(bundleNameList.empty())) {
16561         TLOGW(WmsLogTag::WMS_LIFE, "The number of listeners has reached the upper limit.");
16562         return WMError::WM_ERROR_NO_MEM;
16563     }
16564     taskScheduler_->PostAsyncTask([this, listener, bundleNameList, where = __func__] {
16565         WMError ret = listenerController_->RegisterSessionLifecycleListener(listener, bundleNameList);
16566         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
16567     }, __func__);
16568     return WMError::WM_OK;
16569 }
16570 
UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener> & listener)16571 WMError SceneSessionManager::UnregisterSessionLifecycleListener(const sptr<ISessionLifecycleListener>& listener)
16572 {
16573     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16574         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16575         return WMError::WM_ERROR_INVALID_PERMISSION;
16576     }
16577     if (listener == nullptr) {
16578         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr!");
16579         return WMError::WM_ERROR_INVALID_PARAM;
16580     }
16581     taskScheduler_->PostAsyncTask([this, listener, where = __func__] {
16582         WMError ret = listenerController_->UnregisterSessionLifecycleListener(listener);
16583         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, ret:%{public}d", where, ret);
16584     }, __func__);
16585     return WMError::WM_OK;
16586 }
16587 
SetParentWindowInner(const sptr<SceneSession> & subSession,const sptr<SceneSession> & oldParentSession,const sptr<SceneSession> & newParentSession)16588 WMError SceneSessionManager::SetParentWindowInner(const sptr<SceneSession>& subSession,
16589     const sptr<SceneSession>& oldParentSession, const sptr<SceneSession>& newParentSession)
16590 {
16591     uint32_t oldSubWindowLevel = oldParentSession->GetSessionProperty()->GetSubWindowLevel();
16592     uint32_t newSubWindowLevel = newParentSession->GetSessionProperty()->GetSubWindowLevel();
16593     if (oldSubWindowLevel < newSubWindowLevel &&
16594         subSession->GetMaxSubWindowLevel() + newSubWindowLevel > MAX_SUB_WINDOW_LEVEL) {
16595         TLOGE(WmsLogTag::WMS_SUB, "newParentSession sub level limit");
16596         return WMError::WM_ERROR_INVALID_PARENT;
16597     }
16598     int32_t oldParentWindowId = oldParentSession->GetPersistentId();
16599     int32_t newParentWindowId = newParentSession->GetPersistentId();
16600     subSession->NotifySetParentSession(oldParentWindowId, newParentWindowId);
16601     int32_t subWindowId = subSession->GetPersistentId();
16602     oldParentSession->RemoveSubSession(subWindowId);
16603     newParentSession->AddSubSession(subSession);
16604     subSession->SetParentSession(newParentSession);
16605     subSession->SetParentPersistentId(newParentWindowId);
16606     subSession->UpdateSubWindowLevel(newSubWindowLevel + 1);
16607     if (oldSubWindowLevel == 0) {
16608         oldParentSession->UnregisterNotifySurfaceBoundsChangeFunc(subWindowId);
16609         if (newSubWindowLevel == 0 && subSession->GetIsFollowParentLayout()) {
16610             subSession->SetFollowParentWindowLayoutEnabled(true);
16611         }
16612     }
16613     if (!oldParentSession->IsSameMainSession(newParentSession) && subSession->IsFocused() &&
16614         !subSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
16615         SetHighlightSessionIds(subSession, true);
16616     }
16617     return WMError::WM_OK;
16618 }
16619 
SetParentWindow(int32_t subWindowId,int32_t newParentWindowId)16620 WMError SceneSessionManager::SetParentWindow(int32_t subWindowId, int32_t newParentWindowId)
16621 {
16622     return taskScheduler_->PostSyncTask([this, subWindowId, newParentWindowId, where = __func__] {
16623         auto subSession = GetSceneSession(subWindowId);
16624         if (!subSession || !WindowHelper::IsSubWindow(subSession->GetWindowType())) {
16625             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s subSession is nullptr or type invalid", where);
16626             return WMError::WM_ERROR_INVALID_WINDOW;
16627         }
16628         int32_t oldParentWindowId = subSession->GetParentPersistentId();
16629         auto oldParentSession = GetSceneSession(oldParentWindowId);
16630         if (oldParentSession == nullptr) {
16631             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession is nullptr", where);
16632             return WMError::WM_ERROR_INVALID_PARENT;
16633         }
16634         auto oldWindowType = oldParentSession->GetWindowType();
16635         if (!WindowHelper::IsMainWindow(oldWindowType) && !WindowHelper::IsFloatOrSubWindow(oldWindowType)) {
16636             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s oldParentSession window type invalid", where);
16637             return WMError::WM_ERROR_INVALID_PARENT;
16638         }
16639         auto newParentSession = GetSceneSession(newParentWindowId);
16640         if (newParentSession == nullptr) {
16641             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is nullptr", where);
16642             return WMError::WM_ERROR_INVALID_PARENT;
16643         }
16644         TLOGND(WmsLogTag::WMS_SUB, "%{public}s subWindowId: %{public}d oldParentWindowId: %{public}d "
16645             "newParentWindowId: %{public}d", where, subWindowId, oldParentWindowId, newParentWindowId);
16646         auto newWindowType = newParentSession->GetWindowType();
16647         if (!WindowHelper::IsMainWindow(newWindowType) && !WindowHelper::IsFloatOrSubWindow(newWindowType)) {
16648             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession window type invalid", where);
16649             return WMError::WM_ERROR_INVALID_PARENT;
16650         }
16651         if (oldParentSession->GetCallingPid() != newParentSession->GetCallingPid()) {
16652             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s callingPid not same", where);
16653             return WMError::WM_ERROR_INVALID_PARENT;
16654         }
16655         if (newParentSession->IsAncestorsSession(subWindowId)) {
16656             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s newParentSession is subsession ancestor", where);
16657             return WMError::WM_ERROR_INVALID_PARENT;
16658         }
16659         return SetParentWindowInner(subSession, oldParentSession, newParentSession);
16660     });
16661 }
16662 
NotifyWindowSystemBarPropertyChange(WindowType type,const SystemBarProperty & systemBarProperty)16663 void SceneSessionManager::NotifyWindowSystemBarPropertyChange(
16664     WindowType type, const SystemBarProperty& systemBarProperty)
16665 {
16666     {
16667         std::lock_guard<std::mutex> lock(lastSystemBarPropertyMapMutex_);
16668         auto iter = lastSystemBarPropertyMap_.find(type);
16669         if (iter != lastSystemBarPropertyMap_.end() && iter->second == systemBarProperty) {
16670             TLOGI(WmsLogTag::WMS_IMMS, "type %{public}d prop same as last time.", type);
16671             return;
16672         }
16673         lastSystemBarPropertyMap_[type] = systemBarProperty;
16674     }
16675     SessionManagerAgentController::GetInstance().NotifyWindowSystemBarPropertyChange(type, systemBarProperty);
16676 }
16677 
MinimizeByWindowId(const std::vector<int32_t> & windowIds)16678 WMError SceneSessionManager::MinimizeByWindowId(const std::vector<int32_t>& windowIds)
16679 {
16680     if (!SessionPermission::IsSystemServiceCalling()) {
16681         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system service.");
16682         return WMError::WM_ERROR_INVALID_PERMISSION;
16683     }
16684     if (windowIds.empty()) {
16685         TLOGE(WmsLogTag::WMS_LIFE, "The vector of windowids is empty.");
16686         return WMError::WM_ERROR_INVALID_PARAM;
16687     }
16688     taskScheduler_->PostAsyncTask([this, windowIds, where = __func__]() {
16689         if (minimizeByWindowIdFunc_) {
16690             TLOGNI(WmsLogTag::WMS_PC, "%{public}s", where);
16691             minimizeByWindowIdFunc_(windowIds);
16692         }
16693     }, __func__);
16694     return WMError::WM_OK;
16695 }
16696 
RegisterMinimizeByWindowIdCallback(MinimizeByWindowIdFunc && func)16697 void SceneSessionManager::RegisterMinimizeByWindowIdCallback(MinimizeByWindowIdFunc&& func){
16698     minimizeByWindowIdFunc_ = std::move(func);
16699 }
16700 
GetActiveSceneSessionCopy()16701 const std::vector<sptr<SceneSession>> SceneSessionManager::GetActiveSceneSessionCopy()
16702 {
16703     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
16704     {
16705         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16706         sceneSessionMapCopy = sceneSessionMap_;
16707     }
16708     std::vector<sptr<SceneSession>> activeSession;
16709     for (const auto& elem : sceneSessionMapCopy) {
16710         auto curSession = elem.second;
16711         if (curSession == nullptr) {
16712             TLOGW(WmsLogTag::DEFAULT, "curSession nullptr");
16713             continue;
16714         }
16715         if (curSession->GetSessionInfo().isSystem_ ||
16716             (!curSession->IsSessionForeground())) {
16717              continue;
16718          }
16719         activeSession.push_back(curSession);
16720     }
16721     return activeSession;
16722 }
16723 
RegisterHookSceneSessionActivationFunc(const sptr<SceneSession> & sceneSession)16724 void SceneSessionManager::RegisterHookSceneSessionActivationFunc(const sptr<SceneSession>& sceneSession)
16725 {
16726     TLOGI(WmsLogTag::WMS_LIFE, "in");
16727     sceneSession->HookSceneSessionActivation([](const sptr<SceneSession>& session, bool isNewWant) {
16728         SceneSessionManager::GetInstance().RequestSceneSessionActivation(session, isNewWant);
16729     });
16730 }
16731 
ReportKeyboardCreateException(sptr<SceneSession> & keyboardSession)16732 void SceneSessionManager::ReportKeyboardCreateException(sptr<SceneSession>& keyboardSession) {
16733     std::string msg = "UITYPE:" + std::to_string(static_cast<int32_t>(systemConfig_.windowUIType_)) + ",PanelId:[";
16734     for (const auto& session : GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL)) {
16735         if (!session) {
16736             TLOGW(WmsLogTag::DEFAULT, "session nullptr");
16737             continue;
16738         }
16739         msg +=  "PanelId:" + std::to_string(session->GetPersistentId()) + ",";
16740         msg +=  "screenId:" + std::to_string(session->GetScreenId()) + ",";
16741     }
16742     msg += "],";
16743     for (const auto& session : GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT)) {
16744         if (!session) {
16745             TLOGW(WmsLogTag::DEFAULT, "session nullptr");
16746             continue;
16747         }
16748         msg += "keyboardId:" + std::to_string(session->GetPersistentId()) + ",";
16749         msg += "screenId:" + std::to_string(session->GetScreenId()) + ",";
16750     }
16751     WindowInfoReporter::GetInstance().ReportKeyboardLifeCycleException(
16752         keyboardSession->GetPersistentId(),
16753         KeyboardLifeCycleException::CREATE_EXCEPTION,
16754         msg);
16755 }
16756 
RegisterSceneSessionDestructCallback(NotifySceneSessionDestructFunc && func)16757 void SceneSessionManager::RegisterSceneSessionDestructCallback(NotifySceneSessionDestructFunc&& func)
16758 {
16759     onSceneSessionDestruct_ = std::move(func);
16760 }
16761 
RegisterSceneSessionDestructNotifyManagerFunc(const sptr<SceneSession> & sceneSession)16762 void SceneSessionManager::RegisterSceneSessionDestructNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
16763 {
16764     if (sceneSession == nullptr) {
16765         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
16766         return;
16767     }
16768     sceneSession->SetSceneSessionDestructNotificationFunc([this](int32_t persistentId) {
16769         if (onSceneSessionDestruct_) {
16770             onSceneSessionDestruct_(persistentId);
16771         }
16772     });
16773 }
16774 
RegisterSessionPropertyChangeNotifyManagerFunc(const sptr<SceneSession> & sceneSession)16775 void SceneSessionManager::RegisterSessionPropertyChangeNotifyManagerFunc(const sptr<SceneSession>& sceneSession)
16776 {
16777     if (sceneSession == nullptr) {
16778         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is nullptr");
16779         return;
16780     }
16781     sceneSession->SetSessionPropertyChangeNotifyManagerListener(
16782         [this](int32_t persistentId, WindowInfoKey windowInfoKey) {
16783         NotifySessionPropertyChangeFromSession(persistentId, windowInfoKey);
16784     });
16785 }
16786 
NotifySessionPropertyChangeFromSession(int32_t persistentId,WindowInfoKey windowInfoKey)16787 void SceneSessionManager::NotifySessionPropertyChangeFromSession(int32_t persistentId, WindowInfoKey windowInfoKey)
16788 {
16789     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "persistentId: %{public}d, windowInfoKey: %{public}u",
16790         persistentId, static_cast<uint32_t>(windowInfoKey));
16791     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
16792     if (sceneSession == nullptr) {
16793         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sceneSession nullptr");
16794         return;
16795     }
16796     NotifyWindowPropertyChangeByWindowInfoKey(sceneSession, windowInfoKey);
16797 }
16798 
ConfigSupportZLevel()16799 void SceneSessionManager::ConfigSupportZLevel()
16800 {
16801     TLOGI(WmsLogTag::WMS_HIERARCHY, "support zLevel");
16802     auto task = [this] {
16803         systemConfig_.supportZLevel_ = true;
16804     };
16805     taskScheduler_->PostAsyncTask(task, "ConfigSupportZLevel");
16806 }
16807 
NotifyWindowPropertyChangeByWindowInfoKey(const sptr<SceneSession> & sceneSession,WindowInfoKey windowInfoKey)16808 void SceneSessionManager::NotifyWindowPropertyChangeByWindowInfoKey(
16809     const sptr<SceneSession>& sceneSession, WindowInfoKey windowInfoKey)
16810 {
16811     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "windowInfoKey: %{public}u", static_cast<uint32_t>(windowInfoKey));
16812     std::vector<std::unordered_map<WindowInfoKey, WindowChangeInfoType>> windowInfoList;
16813     std::unordered_map<WindowInfoKey, WindowChangeInfoType> windowPropertyChangeInfo;
16814     PackWindowPropertyChangeInfo(sceneSession, windowPropertyChangeInfo);
16815     windowInfoList.push_back(windowPropertyChangeInfo);
16816     SessionManagerAgentController::GetInstance().NotifyWindowPropertyChange(
16817         static_cast<uint32_t>(windowInfoKey), windowInfoList);
16818 }
16819 
NotifyWindowPropertyChange(ScreenId screenId)16820 void SceneSessionManager::NotifyWindowPropertyChange(ScreenId screenId)
16821 {
16822     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "ObservedFlags: %{public}u, interestedFlags: %{public}u",
16823         observedFlags_, interestedFlags_);
16824     std::vector<std::unordered_map<WindowInfoKey, WindowChangeInfoType>> windowInfoList;
16825     uint32_t propertyDirtyFlags = 0;
16826     {
16827         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
16828         for (const auto& [_, sceneSession] : sceneSessionMap_) {
16829             if (sceneSession == nullptr) {
16830                 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "sceneSession nullptr");
16831                 continue;
16832             }
16833             if (isNotCurrentScreen(sceneSession, screenId)) {
16834                 continue;
16835             }
16836             if (!(sceneSession->GetPropertyDirtyFlags() & observedFlags_)) {
16837                 continue;
16838             }
16839             propertyDirtyFlags |= sceneSession->GetPropertyDirtyFlags();
16840             std::unordered_map<WindowInfoKey, WindowChangeInfoType> windowPropertyChangeInfo;
16841             PackWindowPropertyChangeInfo(sceneSession, windowPropertyChangeInfo);
16842             windowInfoList.emplace_back(windowPropertyChangeInfo);
16843             sceneSession->SetPropertyDirtyFlags(0);
16844         }
16845     }
16846     SessionManagerAgentController::GetInstance().NotifyWindowPropertyChange(propertyDirtyFlags, windowInfoList);
16847 }
16848 
PackWindowPropertyChangeInfo(const sptr<SceneSession> & sceneSession,std::unordered_map<WindowInfoKey,WindowChangeInfoType> & windowPropertyChangeInfo)16849 void SceneSessionManager::PackWindowPropertyChangeInfo(const sptr<SceneSession>& sceneSession,
16850     std::unordered_map<WindowInfoKey, WindowChangeInfoType>& windowPropertyChangeInfo)
16851 {
16852     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::WINDOW_ID)) {
16853         windowPropertyChangeInfo[WindowInfoKey::WINDOW_ID] = sceneSession->GetWindowId();
16854     }
16855     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::BUNDLE_NAME)) {
16856         windowPropertyChangeInfo[WindowInfoKey::BUNDLE_NAME] = sceneSession->GetSessionInfo().bundleName_;
16857     }
16858     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::ABILITY_NAME)) {
16859         windowPropertyChangeInfo[WindowInfoKey::ABILITY_NAME] = sceneSession->GetSessionInfo().abilityName_;
16860     }
16861     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::APP_INDEX)) {
16862         windowPropertyChangeInfo[WindowInfoKey::APP_INDEX] = sceneSession->GetSessionInfo().appIndex_;
16863     }
16864     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::VISIBILITY_STATE)) {
16865         windowPropertyChangeInfo[WindowInfoKey::VISIBILITY_STATE] = sceneSession->GetVisibilityState();
16866     }
16867     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::DISPLAY_ID)) {
16868         if (PcFoldScreenManager::GetInstance().IsHalfFoldedOnMainDisplay(
16869             sceneSession->GetSessionProperty()->GetDisplayId())) {
16870             WSRect sessionGlobalRect = sceneSession->GetSessionGlobalRect();
16871             windowPropertyChangeInfo[WindowInfoKey::DISPLAY_ID] =
16872                 sceneSession->TransformGlobalRectToRelativeRect(sessionGlobalRect);
16873         } else {
16874             windowPropertyChangeInfo[WindowInfoKey::DISPLAY_ID] = sceneSession->GetSessionProperty()->GetDisplayId();
16875         }
16876     }
16877     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::WINDOW_RECT)) {
16878         WSRect wsrect = sceneSession->GetClientRect();
16879         Rect rect = { wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
16880         windowPropertyChangeInfo[WindowInfoKey::WINDOW_RECT] = rect;
16881     }
16882     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::WINDOW_MODE)) {
16883         windowPropertyChangeInfo[WindowInfoKey::WINDOW_MODE] = sceneSession->GetWindowMode();
16884     }
16885     if (interestedFlags_ & static_cast<uint32_t>(SessionPropertyFlag::FLOATING_SCALE)) {
16886         windowPropertyChangeInfo[WindowInfoKey::FLOATING_SCALE] = sceneSession->GetFloatingScale();
16887     }
16888 }
16889 
UseImplicitAnimation(int32_t hostWindowId,bool useImplicit)16890 WSError SceneSessionManager::UseImplicitAnimation(int32_t hostWindowId, bool useImplicit)
16891 {
16892     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d, useImplicit:%{public}d", hostWindowId, useImplicit);
16893     auto task = [this, hostWindowId, useImplicit]() {
16894         auto sceneSession = GetSceneSession(hostWindowId);
16895         if (sceneSession == nullptr) {
16896             TLOGNE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
16897             return WSError::WS_ERROR_INVALID_SESSION;
16898         }
16899         return sceneSession->UseImplicitAnimation(useImplicit);
16900     };
16901 
16902     return taskScheduler_->PostSyncTask(task, "UseImplicitAnimation");
16903 }
16904 
GetApplicationInfo(const std::string & bundleName,SCBApplicationInfo & scbApplicationInfo)16905 WSError SceneSessionManager::GetApplicationInfo(const std::string& bundleName, SCBApplicationInfo& scbApplicationInfo)
16906 {
16907     AppExecFwk::ApplicationInfo applicationInfo;
16908     applicationInfo = MultiInstanceManager::GetInstance().GetApplicationInfo(bundleName);
16909     scbApplicationInfo.startMode_ = applicationInfo.startMode;
16910     return WSError::WS_OK;
16911 }
16912 
GetRecentMainSessionInfoList(std::vector<RecentSessionInfo> & recentSessionInfoList)16913 WSError SceneSessionManager::GetRecentMainSessionInfoList(std::vector<RecentSessionInfo>& recentSessionInfoList)
16914 {
16915     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16916         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16917         return WSError::WS_ERROR_INVALID_PERMISSION;
16918     }
16919     if (!recentSessionInfoList.empty()) {
16920         TLOGE(WmsLogTag::WMS_LIFE, "the recent session info list is already loaded");
16921         return WSError::WS_ERROR_INVALID_PARAM;
16922     }
16923     return taskScheduler_->PostSyncTask([this, &recentSessionInfoList, where = __func__] {
16924         for (auto& recentSessionInfo : this->recentMainSessionInfoList_) {
16925             if (auto session = GetMainSessionByPersistentId(recentSessionInfo.missionId)) {
16926                 session->SetRecentSessionState(recentSessionInfo, session->GetSessionState());
16927                 TLOGI(WmsLogTag::WMS_LIFE, "get recent main session info of id:%{public}d, bundleName:%{public}s, "
16928                     "moduleName:%{public}s, abilityName:%{public}s, sessionState:%{public}d, windowType:%{public}d",
16929                     recentSessionInfo.missionId, recentSessionInfo.bundleName.c_str(),
16930                     recentSessionInfo.moduleName.c_str(), recentSessionInfo.abilityName.c_str(),
16931                     recentSessionInfo.sessionState, recentSessionInfo.windowType);
16932                 recentSessionInfoList.emplace_back(recentSessionInfo);
16933             }
16934         }
16935         return WSError::WS_OK;
16936     });
16937 }
16938 
UpdateRecentMainSessionInfos(const std::vector<int32_t> & recentMainSessionIdList)16939 void SceneSessionManager::UpdateRecentMainSessionInfos(const std::vector<int32_t>& recentMainSessionIdList)
16940 {
16941     taskScheduler_->PostAsyncTask([this, recentMainSessionIdList, where = __func__]() {
16942         this->recentMainSessionInfoList_.clear();
16943 
16944         for (int32_t persistentId : recentMainSessionIdList) {
16945             if (auto session = GetMainSessionByPersistentId(persistentId)) {
16946                 const auto& sessionInfo  = session->GetSessionInfo();
16947                 RecentSessionInfo info(persistentId);
16948                 info.bundleName = sessionInfo.bundleName_;
16949                 info.moduleName = sessionInfo.moduleName_;
16950                 info.abilityName = sessionInfo.abilityName_;
16951                 info.appIndex = sessionInfo.appIndex_;
16952                 info.windowType = session->GetWindowType();
16953 
16954                 this->recentMainSessionInfoList_.emplace_back(info);
16955             }
16956         }
16957     }, __func__);
16958 }
16959 
RegisterTransferSessionToTargetScreenCallback(NotifyTransferSessionToTargetScreenFunc && func)16960 void SceneSessionManager::RegisterTransferSessionToTargetScreenCallback(NotifyTransferSessionToTargetScreenFunc&& func)
16961 {
16962     taskScheduler_->PostAsyncTask([this, func] {
16963         onTransferSessionToTargetScreen_ = std::move(func);
16964     }, __func__);
16965 }
16966 
NotifyTransferSessionToTargetScreen(const TransferSessionInfo & info)16967 WMError SceneSessionManager::NotifyTransferSessionToTargetScreen(const TransferSessionInfo& info)
16968 {
16969     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
16970         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
16971         return WMError::WM_ERROR_INVALID_PERMISSION;
16972     }
16973     if (info.persistentId < 0 || info.toScreenId < 0) {
16974         TLOGE(WmsLogTag::WMS_LIFE, "Param is invalid!");
16975         return WMError::WM_ERROR_INVALID_PARAM;
16976     }
16977     taskScheduler_->PostAsyncTask([this, info, where = __func__]() {
16978         if (onTransferSessionToTargetScreen_) {
16979             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, persistentId: %{public}d toScreenId: %{public}d",
16980                 where, info.persistentId, info.toScreenId);
16981             onTransferSessionToTargetScreen_(info);
16982         }
16983     }, __func__);
16984     return WMError::WM_OK;
16985 }
16986 
NotifySessionTransferToTargetScreenEvent(const int32_t persistentId,const uint32_t resultCode,const uint64_t fromScreenId,const uint64_t toScreenId)16987 void SceneSessionManager::NotifySessionTransferToTargetScreenEvent(const int32_t persistentId,
16988     const uint32_t resultCode, const uint64_t fromScreenId, const uint64_t toScreenId)
16989 {
16990     auto sceneSession = GetSceneSession(persistentId);
16991     if (sceneSession == nullptr) {
16992         TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is nullptr");
16993         return;
16994     }
16995     listenerController_->NotifySessionTransferToTargetScreenEvent(
16996         sceneSession->GetSessionInfo(), resultCode, fromScreenId, toScreenId);
16997 }
16998 
AnimateTo(int32_t windowId,const WindowAnimationProperty & animationProperty,const WindowAnimationOption & animationOption)16999 WMError SceneSessionManager::AnimateTo(int32_t windowId, const WindowAnimationProperty& animationProperty,
17000         const WindowAnimationOption& animationOption)
17001 {
17002     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
17003         TLOGE(WmsLogTag::WMS_ANIMATION, "Permission denied, only for SA");
17004         return WMError::WM_ERROR_INVALID_PERMISSION;
17005     }
17006     auto session = GetSceneSession(windowId);
17007     if (session == nullptr || SessionHelper::IsSystemWindow(session->GetWindowType())) {
17008         TLOGNE(WmsLogTag::WMS_ANIMATION, "Can not find window or is system window");
17009         return WMError::WM_DO_NOTHING;
17010     }
17011     session->AnimateTo(animationProperty, animationOption);
17012     return WMError::WM_OK;
17013 }
17014 
GetRouterStackInfo(int32_t persistentId,const sptr<ISessionRouterStackListener> & listener)17015 WMError SceneSessionManager::GetRouterStackInfo(int32_t persistentId,
17016     const sptr<ISessionRouterStackListener>& listener)
17017 {
17018     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17019         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17020         return WMError::WM_ERROR_INVALID_PERMISSION;
17021     }
17022     if (listener == nullptr) {
17023         TLOGE(WmsLogTag::WMS_LIFE, "listener is nullptr.");
17024         return WMError::WM_ERROR_NULLPTR;
17025     }
17026     auto session = GetSceneSession(persistentId);
17027     if (session == nullptr) {
17028         TLOGE(WmsLogTag::WMS_LIFE, "Session with persistentId %{public}d not found", persistentId);
17029         return WMError::WM_ERROR_NULLPTR;
17030     }
17031     auto task = [this, weakSceneSession = wptr(session), listener, where = __func__] {
17032         sptr<SceneSession> session = weakSceneSession.promote();
17033         if (session == nullptr) {
17034             TLOGNE(WmsLogTag::WMS_LIFE, "session is nullptr");
17035             return;
17036         }
17037         std::string routerStack;
17038         auto ret = session->GetRouterStackInfo(routerStack);
17039         sptr<RouterStackInfo> routerStackInfo = sptr<RouterStackInfo>::MakeSptr(session->GetPersistentId(), routerStack);
17040         if (ret != WMError::WM_OK) {
17041             TLOGNE(WmsLogTag::WMS_LIFE, "failed, persistentId %{public}d", session->GetPersistentId());
17042             routerStackInfo->errCode_ = ret;
17043             listener->SendRouterStackInfo(routerStackInfo);
17044             return;
17045         }
17046         listener->SendRouterStackInfo(routerStackInfo);
17047     };
17048     ffrtQueueHelper_->SubmitTask(task);
17049     return WMError::WM_OK;
17050 }
17051 
CreateNewInstanceKey(const std::string & bundleName,std::string & instanceKey)17052 WMError SceneSessionManager::CreateNewInstanceKey(const std::string& bundleName, std::string& instanceKey)
17053 {
17054     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17055         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17056         return WMError::WM_ERROR_INVALID_PERMISSION;
17057     }
17058     if (bundleName.empty()) {
17059         TLOGE(WmsLogTag::WMS_LIFE, "empty bundleName");
17060         return WMError::WM_ERROR_INVALID_PARAM;
17061     }
17062     uint32_t maxInstanceCount = MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
17063     uint32_t instanceCount = GetInstanceCount(bundleName);
17064     if (instanceCount < maxInstanceCount) {
17065         instanceKey = MultiInstanceManager::GetInstance().CreateNewInstanceKey(bundleName);
17066     } else {
17067         instanceKey = MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
17068     }
17069     TLOGI(WmsLogTag::WMS_LIFE, "create new instanceKey:%{public}s of bundle:%{public}s",
17070         instanceKey.c_str(), bundleName.c_str());
17071     return WMError::WM_OK;
17072 }
17073 
RemoveInstanceKey(const std::string & bundleName,const std::string & instanceKey)17074 WMError SceneSessionManager::RemoveInstanceKey(const std::string& bundleName, const std::string& instanceKey)
17075 {
17076     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17077         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17078         return WMError::WM_ERROR_INVALID_PERMISSION;
17079     }
17080     if (bundleName.empty()) {
17081         TLOGE(WmsLogTag::WMS_LIFE, "empty bundleName");
17082         return WMError::WM_ERROR_INVALID_PARAM;
17083     }
17084     if (instanceKey.empty()) {
17085         TLOGE(WmsLogTag::WMS_LIFE, "empty instanceKey");
17086         return WMError::WM_ERROR_INVALID_PARAM;
17087     }
17088     auto task = [bundleName, instanceKey] {
17089         MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCountByBundleNameAndInstanceKey(
17090             bundleName, instanceKey);
17091     };
17092     taskScheduler_->PostAsyncTask(task, __func__);
17093     TLOGI(WmsLogTag::WMS_LIFE, "remove instanceKey:%{public}s of bundle:%{public}s",
17094         instanceKey.c_str(), bundleName.c_str());
17095     return WMError::WM_OK;
17096 }
17097 
UpdateKioskAppList(const std::vector<std::string> & kioskAppList)17098 WMError SceneSessionManager::UpdateKioskAppList(const std::vector<std::string>& kioskAppList)
17099 {
17100     TLOGI(WmsLogTag::WMS_LIFE, "kioskAppList size: %{public}zu", kioskAppList.size());
17101     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17102         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17103         return WMError::WM_ERROR_INVALID_PERMISSION;
17104     }
17105     if (kioskAppList.empty()) {
17106         TLOGE(WmsLogTag::WMS_LIFE, "empty kioskAppList");
17107         return WMError::WM_ERROR_INVALID_PARAM;
17108     }
17109     taskScheduler_->PostAsyncTask([this, kioskAppList] {
17110         if (updateKioskAppListFunc_ != nullptr) {
17111             updateKioskAppListFunc_(kioskAppList);
17112             return WMError::WM_OK;
17113         }
17114         kioskAppListCache_ = kioskAppList;
17115         return WMError::WM_OK;
17116     }, __func__);
17117     return WMError::WM_OK;
17118 }
17119 
RegisterUpdateKioskAppListCallback(UpdateKioskAppListFunc && func)17120 void SceneSessionManager::RegisterUpdateKioskAppListCallback(UpdateKioskAppListFunc&& func)
17121 {
17122     taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
17123         updateKioskAppListFunc_ = std::move(callback);
17124         if (!kioskAppListCache_.empty()) {
17125             updateKioskAppListFunc_(kioskAppListCache_);
17126         }
17127     }, __func__);
17128 }
17129 
EnterKioskMode(const sptr<IRemoteObject> & token)17130 WMError SceneSessionManager::EnterKioskMode(const sptr<IRemoteObject>& token)
17131 {
17132     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17133         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17134         return WMError::WM_ERROR_INVALID_PERMISSION;
17135     }
17136     taskScheduler_->PostAsyncTask([this, token, where = __func__] {
17137         auto session = FindSessionByToken(token, WindowType::WINDOW_TYPE_APP_MAIN_WINDOW);
17138         if (session == nullptr) {
17139             TLOGNE(WmsLogTag::WMS_LIFE, "token is invalid");
17140             return WMError::WM_ERROR_INVALID_PARAM;
17141         }
17142         if (kioskModeChangeFunc_ != nullptr) {
17143             kioskModeChangeFunc_(true, session->GetPersistentId());
17144             return WMError::WM_OK;
17145         }
17146         isKioskMode_ = true;
17147         kioskAppPersistentId_ = session->GetPersistentId();
17148         return WMError::WM_OK;
17149     }, __func__);
17150     return WMError::WM_OK;
17151 }
17152 
ExitKioskMode()17153 WMError SceneSessionManager::ExitKioskMode()
17154 {
17155     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
17156         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
17157         return WMError::WM_ERROR_INVALID_PERMISSION;
17158     }
17159     taskScheduler_->PostAsyncTask([this, where = __func__] {
17160         if (kioskModeChangeFunc_ != nullptr) {
17161             kioskModeChangeFunc_(false, INVALID_SESSION_ID);
17162             return WMError::WM_OK;
17163         }
17164         isKioskMode_ = false;
17165         kioskAppPersistentId_ = INVALID_SESSION_ID;
17166         return WMError::WM_OK;
17167     }, __func__);
17168     return WMError::WM_OK;
17169 }
17170 
RegisterKioskModeChangeCallback(KioskModeChangeFunc && func)17171 void SceneSessionManager::RegisterKioskModeChangeCallback(KioskModeChangeFunc&& func)
17172 {
17173     taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
17174         kioskModeChangeFunc_ = std::move(callback);
17175         kioskModeChangeFunc_(isKioskMode_, kioskAppPersistentId_);
17176     }, __func__);
17177 }
17178 
GetSceneSessions(ScreenId screenId)17179 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessions(ScreenId screenId)
17180 {
17181     std::vector<sptr<SceneSession>> sceneSessions;
17182     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
17183     for (const auto& [_, sceneSession] : sceneSessionMap_) {
17184         if (sceneSession != nullptr && sceneSession->GetScreenId() == screenId) {
17185             sceneSessions.emplace_back(sceneSession);
17186         }
17187     }
17188     TLOGD(WmsLogTag::WMS_LAYOUT, "screenId: %{public}" PRIu64 ", sceneSession count: %{public}zu",
17189         screenId, sceneSessions.size());
17190     return sceneSessions;
17191 }
17192 
SetPiPSettingSwitchStatus(bool switchStatus)17193 void SceneSessionManager::SetPiPSettingSwitchStatus(bool switchStatus)
17194 {
17195     std::lock_guard<std::mutex> lock(pipSettingSwitchMutex_);
17196     pipSwitchStatus_ = switchStatus;
17197 }
17198 
GetPiPSettingSwitchStatus(bool & switchStatus)17199 WMError SceneSessionManager::GetPiPSettingSwitchStatus(bool& switchStatus)
17200 {
17201     std::lock_guard<std::mutex> lock(pipSettingSwitchMutex_);
17202     switchStatus = pipSwitchStatus_;
17203     return WMError::WM_OK;
17204 }
17205 
UpdateScreenLockState(int32_t persistentId)17206 WMError SceneSessionManager::UpdateScreenLockState(int32_t persistentId)
17207 {
17208     if (persistentId < 0) {
17209         TLOGE(WmsLogTag::WMS_LIFE, "Param is invalid!");
17210         return WMError::WM_ERROR_INVALID_PARAM;
17211     }
17212     taskScheduler_->PostAsyncTask([this, persistentId, where = __func__]() {
17213         auto sceneSession = GetSceneSession(persistentId);
17214         if (sceneSession != nullptr) {
17215             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn(), WINDOW_SCREEN_LOCK_PREFIX,
17216                                sceneSession->keepScreenLock_);
17217         }
17218     }, __func__);
17219     return WMError::WM_OK;
17220 }
17221 
UpdateSystemDecorEnable(bool enable)17222 WMError SceneSessionManager::UpdateSystemDecorEnable(bool enable)
17223 {
17224     TLOGI(WmsLogTag::WMS_DECOR, "set system decor enable: %{public}d", enable);
17225     systemConfig_.isSystemDecorEnable_ = enable;
17226     return WMError::WM_OK;
17227 }
17228 } // namespace OHOS::Rosen
17229