• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "session_manager/include/scene_session_manager.h"
17 
18 #include <regex>
19 
20 #include <ability_context.h>
21 #include <ability_manager_client.h>
22 #include <application_context.h>
23 #include <bundlemgr/launcher_service.h>
24 #include <hisysevent.h>
25 #include <parameters.h>
26 #include <hitrace_meter.h>
27 #include "parameter.h"
28 #include "publish/scb_dump_subscriber.h"
29 #include <ui/rs_node.h>
30 
31 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
32 #include <display_power_mgr_client.h>
33 #endif
34 
35 #ifdef POWER_MANAGER_ENABLE
36 #include <power_mgr_client.h>
37 #endif
38 
39 #ifdef RES_SCHED_ENABLE
40 #include "res_type.h"
41 #include "res_sched_client.h"
42 #endif
43 #include "scene_system_ability_listener.h"
44 
45 #include "anr_manager.h"
46 #include "color_parser.h"
47 #include "common/include/session_permission.h"
48 #include "display_manager.h"
49 #include "scene_input_manager.h"
50 #include "session/host/include/main_session.h"
51 #include "session/host/include/scb_system_session.h"
52 #include "session/host/include/scene_persistent_storage.h"
53 #include "session/host/include/session_utils.h"
54 #include "session/host/include/sub_session.h"
55 #include "session_helper.h"
56 #include "window_helper.h"
57 #include "screen_session_manager/include/screen_session_manager_client.h"
58 #include "singleton_container.h"
59 #include "xcollie/watchdog.h"
60 #include "session_manager_agent_controller.h"
61 #include "distributed_client.h"
62 #include "softbus_bus_center.h"
63 #include "perform_reporter.h"
64 #include "anr_manager.h"
65 #include "dms_reporter.h"
66 #include "res_sched_client.h"
67 #include "anomaly_detection.h"
68 #include "session/host/include/ability_info_manager.h"
69 
70 #ifdef MEMMGR_WINDOW_ENABLE
71 #include "mem_mgr_client.h"
72 #include "mem_mgr_window_info.h"
73 #endif
74 
75 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
76 #include "sec_comp_enhance_kit.h"
77 #endif
78 
79 #ifdef IMF_ENABLE
80 #include <input_method_controller.h>
81 #endif // IMF_ENABLE
82 
83 namespace OHOS::Rosen {
84 namespace {
85 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
86 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
87 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
88 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
89 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
90 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
91 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
92 constexpr uint32_t MAX_BRIGHTNESS = 255;
93 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
94 constexpr int32_t SCALE_DIMENSION = 2;
95 constexpr int32_t TRANSLATE_DIMENSION = 2;
96 constexpr int32_t ROTAION_DIMENSION = 4;
97 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
98 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
99 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
100 const std::string EMPTY_DEVICE_ID = "";
101 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
102 
103 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
104 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
105 constexpr int VALUE_MAX_WIDTH = 5;
106 constexpr int MAX_RESEND_TIMES = 6;
107 constexpr int ORIEN_MAX_WIDTH = 12;
108 constexpr int OFFSET_MAX_WIDTH = 8;
109 constexpr int SCALE_MAX_WIDTH = 8;
110 constexpr int PID_MAX_WIDTH = 8;
111 constexpr int PARENT_ID_MAX_WIDTH = 6;
112 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
113 constexpr int32_t CANCEL_POINTER_ID = 99999999;
114 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
115 const std::string ARG_DUMP_ALL = "-a";
116 const std::string ARG_DUMP_WINDOW = "-w";
117 const std::string ARG_DUMP_SCREEN = "-s";
118 const std::string ARG_DUMP_DISPLAY = "-d";
119 const std::string ARG_DUMP_PIPLINE = "-p";
120 const std::string ARG_DUMP_SCB = "-b";
121 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
122 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
123 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
124 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
125 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PC = 50;
126 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PAD = 8;
127 constexpr std::size_t MAX_SNAPSHOT_IN_RECENT_PHONE = 3;
128 constexpr int32_t MAX_LOCK_STATUS_CACHE_SIZE = 1000;
129 
130 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
131     {"unspecified",                         OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
132     {"landscape",                           OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
133     {"portrait",                            OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
134     {"follow_recent",                       OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
135     {"landscape_inverted",                  OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
136     {"portrait_inverted",                   OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
137     {"auto_rotation",                       OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
138     {"auto_rotation_landscape",             OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
139     {"auto_rotation_portrait",              OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
140     {"auto_rotation_restricted",            OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
141     {"auto_rotation_landscape_restricted",  OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
142     {"auto_rotation_portrait_restricted",   OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
143     {"locked",                              OHOS::AppExecFwk::DisplayOrientation::LOCKED},
144     {"auto_rotation_unspecified",           OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
145     {"follow_desktop",                      OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
146 };
147 
148 const std::unordered_set<std::string> LAYOUT_INFO_WHITELIST = {
149     "SCBSmartDock",
150     "SCBExtScreenDock",
151     "status_bar_tray",
152     "status_bar_personal",
153     "status_bar_sound_panel",
154     "status_bar_notification_panel",
155     "status_bar_input_panel",
156     "status_bar_control_center",
157     "status_bar_wifi_panel",
158     "status_bar_input_method",
159     "status_bar_assistant_translate",
160     "status_bar_quick_note",
161     "status_bar_bluetooth_panel",
162     "status_bar_battery_panel",
163     "status_bar_focus_mode_paddle",
164     "SCBStatusBar"
165 };
166 
167 static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
168 
169 static std::shared_ptr<ScbDumpSubscriber> g_scbSubscriber(nullptr);
170 
GetCurrentTime()171 std::string GetCurrentTime()
172 {
173     struct timespec tn;
174     clock_gettime(CLOCK_REALTIME, &tn);
175     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
176         static_cast<uint64_t>(tn.tv_nsec);
177     return std::to_string(uTime);
178 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)179 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
180 {
181     return a.first < b.first;
182 }
183 
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)184 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
185 {
186     if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
187         value = (*item.intsValue_)[0];
188         return true;
189     }
190     return false;
191 }
192 
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)193 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
194 {
195     auto& metadata = abilityInfo->metadata;
196     for (const auto& item : metadata) {
197         if (item.name == "enable.remove.starting.window") {
198             return item.value == "true";
199         }
200     }
201     return false;
202 }
203 
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)204 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
205     AppExecFwk::ExtensionAbilityType extensionAbilityType)
206 {
207     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
208           element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
209     static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
210         AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
211     };
212     static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
213         std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
214         std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
215         std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
216         std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
217         std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
218         std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
219         std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
220         std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
221         std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
222         std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
223         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
224         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
225         std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
226         std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
227         std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
228         std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
229         std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
230         std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
231         std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
232         std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
233     };
234 
235     if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
236         TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: extensionAbilityType in white list");
237         return true;
238     }
239 
240     auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
241         auto& [bundleName, abilityName, _] = item;
242         return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
243     });
244     if (it != elementNameWhitelist.end()) {
245         return true;
246     }
247 
248     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
249     return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
250         PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
251 }
252 
253 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
254 public:
255     BundleStatusCallback() = default;
256     virtual ~BundleStatusCallback() = default;
257 
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)258     void OnBundleStateChanged(const uint8_t installType,
259         const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
260 
OnBundleAdded(const std::string & bundleName,const int userId)261     void OnBundleAdded(const std::string& bundleName, const int userId) override
262     {
263         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
264     }
265 
OnBundleUpdated(const std::string & bundleName,const int userId)266     void OnBundleUpdated(const std::string& bundleName, const int userId) override
267     {
268         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
269     }
270 
OnBundleRemoved(const std::string & bundleName,const int userId)271     void OnBundleRemoved(const std::string& bundleName, const int userId) override
272     {
273         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
274     }
275 };
276 
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)277 bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
278 {
279     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
280         !avoidArea.rightRect_.IsUninitializedRect()) {
281         return false;
282     }
283     if (avoidArea.bottomRect_.IsUninitializedRect()) {
284         return true;
285     }
286     auto diff =
287         std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
288     return isVisible && diff <= 1;
289 }
290 } // namespace
291 
CreateInstance()292 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
293 {
294     sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
295     sessionManager->Init();
296     return sessionManager;
297 }
298 
GetInstance()299 SceneSessionManager& SceneSessionManager::GetInstance()
300 {
301     static sptr<SceneSessionManager> instance = CreateInstance();
302     return *instance;
303 }
304 
SceneSessionManager()305 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
306 {
307     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
308     if (!mainHandler_) {
309         auto runner = AppExecFwk::EventRunner::GetMainEventRunner();
310         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
311     }
312     currentUserId_ = DEFAULT_USERID;
313     launcherService_ = new AppExecFwk::LauncherService();
314     if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
315         WLOGFE("Failed to register bundle status callback.");
316     }
317     ScbDumpSubscriber::Subscribe(g_scbSubscriber);
318 }
319 
~SceneSessionManager()320 SceneSessionManager::~SceneSessionManager()
321 {
322     ScbDumpSubscriber::UnSubscribe(g_scbSubscriber);
323 }
324 
Init()325 void SceneSessionManager::Init()
326 {
327     auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
328     bool isScbCoreEnabled = (deviceType == UI_TYPE_PHONE || deviceType == "tablet") &&
329         system::GetParameter("persist.window.scbcore.enable", "1") == "1";
330     Session::SetScbCoreEnabled(isScbCoreEnabled);
331 
332     constexpr uint64_t interval = 5 * 1000; // 5 second
333     if (HiviewDFX::Watchdog::GetInstance().AddThread(
334         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
335         WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
336     }
337 
338     bundleMgr_ = GetBundleManager();
339     LoadWindowSceneXml();
340     sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
341     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
342     InitPrepareTerminateConfig();
343     // create handler for inner command at server
344     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
345     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
346     if (eventHandler_ == nullptr) {
347         WLOGFE("Invalid eventHander");
348         return ;
349     }
350     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
351     if (ret != 0) {
352         WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
353     }
354 
355     listenerController_ = std::make_shared<SessionListenerController>();
356     listenerController_->Init();
357     scbSessionHandler_ = new ScbSessionHandler();
358     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
359     StartWindowInfoReportLoop();
360     WLOGI("SSM init success.");
361     RegisterAppListener();
362     openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
363     isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1")  == "1";
364     SceneInputManager::GetInstance().Init();
365 
366     // MMI window state error check
367     int32_t retCode = MMI::InputManager::GetInstance()->
368         RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
369         this->NotifyWindowStateErrorFromMMI(pid, persistentId);
370     });
371     TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
372 
373     AbilityInfoManager::GetInstance().Init(bundleMgr_);
374     AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
375     UpdateDarkColorModeToRS();
376 
377     InitSnapshotCache();
378 }
379 
InitScheduleUtils()380 void SceneSessionManager::InitScheduleUtils()
381 {
382 #ifdef RES_SCHED_ENABLE
383     SCBThreadInfo threadInfo = {
384         .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
385         .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
386     };
387     std::unordered_map<std::string, std::string> payload {
388         { "pid", threadInfo.scbPid_ },
389         { "tid", threadInfo.scbTid_ },
390         { "uid", threadInfo.scbUid_ },
391         { "bundleName", threadInfo.scbBundleName_ },
392     };
393     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
394     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
395     auto task = [threadInfo = std::move(threadInfo)]() mutable {
396         threadInfo.ssmThreadName_ = "OS_SceneSession";
397         threadInfo.ssmTid_ = std::to_string(gettid());
398         const int32_t userInteraction = 2;
399         std::unordered_map<std::string, std::string> payload{
400             { "pid", threadInfo.scbPid_ },
401             { "tid", threadInfo.ssmTid_ },
402             { "uid", threadInfo.scbUid_ },
403             { "extType", "10002" },
404             { "cgroupPrio", "1" },
405             { "isSa", "0" },
406             { "threadName", threadInfo.ssmThreadName_ }
407         };
408         uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
409         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
410         TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
411         sptr<ISystemAbilityManager> systemAbilityManager =
412             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
413         if (!systemAbilityManager) {
414             TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
415             return;
416         }
417         auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
418         int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
419         if (ret != ERR_OK) {
420             TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
421         }
422     };
423     taskScheduler_->PostAsyncTask(task, "changeQosTask");
424 #endif
425 }
426 
RegisterAppListener()427 void SceneSessionManager::RegisterAppListener()
428 {
429     appAnrListener_ = new (std::nothrow) AppAnrListener();
430     auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
431     if (appMgrClient_ == nullptr) {
432         WLOGFE("appMgrClient_ is nullptr.");
433     } else if (appAnrListener_ == nullptr) {
434         WLOGFE("appAnrListener_ is nullptr.");
435     } else {
436         auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
437         if (flag != ERR_OK) {
438             WLOGFE("Register app debug listener failed.");
439         } else {
440             WLOGFI("Register app debug listener success.");
441         }
442     }
443 }
444 
LoadWindowSceneXml()445 void SceneSessionManager::LoadWindowSceneXml()
446 {
447     if (WindowSceneConfig::LoadConfigXml()) {
448         if (WindowSceneConfig::GetConfig().IsMap()) {
449             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
450         }
451         ConfigWindowSceneXml();
452     } else {
453         WLOGFE("Load window scene xml failed");
454     }
455     ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
456         appWindowSceneConfig_.keyboardAnimationOut_);
457 }
458 
InitPrepareTerminateConfig()459 void SceneSessionManager::InitPrepareTerminateConfig()
460 {
461     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
462     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
463         PREPARE_TERMINATE_ENABLE_SIZE);
464     WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
465     if (retSysParam > 0 && !std::strcmp(value, "true")) {
466         isPrepareTerminateEnable_ = true;
467     }
468 }
469 
ConfigWindowSceneXml()470 void SceneSessionManager::ConfigWindowSceneXml()
471 {
472     const auto& config = WindowSceneConfig::GetConfig();
473     WindowSceneConfig::ConfigItem item = config["windowEffect"];
474     if (item.IsMap()) {
475         ConfigWindowEffect(item);
476     }
477 
478     item = config["decor"];
479     if (item.IsMap()) {
480         ConfigDecor(item);
481     }
482 
483     item = config["backgroundswitch"];
484     if (item.IsInts()) {
485         auto numbers = *item.intsValue_;
486         if (numbers.size() == 1 && numbers[0] == 1) {
487             systemConfig_.backgroundswitch = true;
488         }
489     }
490     WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
491 
492     item = config["defaultWindowMode"];
493     if (item.IsInts()) {
494         auto numbers = *item.intsValue_;
495         if (numbers.size() == 1 &&
496             (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
497              numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
498             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
499         }
500     }
501 
502     item = config["defaultMaximizeMode"];
503     if (item.IsInts()) {
504         auto numbers = *item.intsValue_;
505         if (numbers.size() == 1 &&
506             (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
507             numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
508             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
509         }
510     }
511 
512     item = config["keyboardAnimation"];
513     if (item.IsMap()) {
514         ConfigKeyboardAnimation(item);
515     }
516 
517     item = config["maxFloatingWindowSize"];
518     if (item.IsInts()) {
519         auto numbers = *item.intsValue_;
520         if (numbers.size() == 1) {
521             systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
522         }
523     }
524 
525     item = config["windowAnimation"];
526     if (item.IsMap()) {
527         ConfigWindowAnimation(item);
528     }
529 
530     item = config["startWindowTransitionAnimation"];
531     if (item.IsMap()) {
532         ConfigStartingWindowAnimation(item);
533     }
534     item = config["maxMidSceneNum"];
535     if (item.IsInts()) {
536         auto numbers = *item.intsValue_;
537         if (numbers.size() == 1) {
538             systemConfig_.maxMidSceneNum_ = static_cast<uint32_t>(numbers[0]);
539         }
540     }
541     ConfigFreeMultiWindow();
542     ConfigWindowSizeLimits();
543     ConfigSnapshotScale();
544     ConfigWindowSceneXml(config);
545 }
546 
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)547 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
548 {
549     WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
550     if (item.IsMap()) {
551         ConfigSystemUIStatusBar(item);
552     }
553     item = config["uiType"];
554     if (item.IsString()) {
555         systemConfig_.uiType_ = item.stringValue_;
556         appWindowSceneConfig_.uiType_ = item.stringValue_;
557     }
558     item = config["backgroundScreenLock"].GetProp("enable");
559     if (item.IsBool()) {
560         appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
561     }
562     item = config["rotationMode"];
563     if (item.IsString()) {
564         appWindowSceneConfig_.rotationMode_ = item.stringValue_;
565     }
566     item = config["immersive"];
567     if (item.IsMap()) {
568         ConfigWindowImmersive(item);
569     }
570     item = config["supportTypeFloatWindow"].GetProp("enable");
571     if (item.IsBool()) {
572         systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
573     }
574 }
575 
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)576 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
577 {
578     AppWindowSceneConfig config;
579     WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
580     if (item.IsMap()) {
581         if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
582             appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
583                 config.windowImmersive_.desktopStatusBarConfig_;
584         }
585     }
586     item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
587     if (item.IsMap()) {
588         if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
589             appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
590                 config.windowImmersive_.upDownStatusBarConfig_;
591         }
592     }
593     item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
594     if (item.IsMap()) {
595         if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
596             appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
597                 config.windowImmersive_.leftRightStatusBarConfig_;
598         }
599     }
600 }
601 
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)602 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
603     StatusBarConfig& statusBarConfig)
604 {
605     WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
606     if (item.IsBool()) {
607         statusBarConfig.showHide_ = item.boolValue_;
608     }
609     item = config["contentColor"];
610     if (item.IsString()) {
611         statusBarConfig.contentColor_ = item.stringValue_;
612     }
613     item = config["backgroundColor"];
614     if (item.IsString()) {
615         statusBarConfig.backgroundColor_ = item.stringValue_;
616     }
617     return true;
618 }
619 
ConfigFreeMultiWindow()620 void SceneSessionManager::ConfigFreeMultiWindow()
621 {
622     const auto& config = WindowSceneConfig::GetConfig();
623     WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
624     if (freeMultiWindowConfig.IsMap()) {
625         auto supportItem = freeMultiWindowConfig.GetProp("enable");
626         if (supportItem.IsBool()) {
627             systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
628         }
629         auto item = freeMultiWindowConfig["decor"];
630         if (item.IsMap()) {
631             ConfigDecor(item, false);
632         }
633         int32_t param = -1;
634         item = freeMultiWindowConfig["defaultWindowMode"];
635         if (GetSingleIntItem(item, param) &&
636             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
637             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
638             systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
639                 static_cast<WindowMode>(static_cast<uint32_t>(param));
640         }
641         item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
642         if (GetSingleIntItem(item, param) && (param > 0)) {
643             systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
644         }
645     }
646 }
647 
LoadFreeMultiWindowConfig(bool enable)648 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
649 {
650     FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
651     if (enable) {
652         systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
653         systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
654         systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
655     } else {
656         const auto& config = WindowSceneConfig::GetConfig();
657         auto item = config["decor"];
658         if (item.IsMap()) {
659             ConfigDecor(item, true);
660         }
661         int32_t param = -1;
662         item = config["defaultWindowMode"];
663         if (GetSingleIntItem(item, param) &&
664             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
665             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
666             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
667         }
668     }
669     systemConfig_.freeMultiWindowEnable_ = enable;
670 }
671 
GetSystemSessionConfig() const672 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
673 {
674     return systemConfig_;
675 }
676 
SwitchFreeMultiWindow(bool enable)677 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
678 {
679     if (!systemConfig_.freeMultiWindowSupport_) {
680         TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
681         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
682     }
683     LoadFreeMultiWindowConfig(enable);
684     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
685     for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
686         auto sceneSession = item->second;
687         if (sceneSession == nullptr) {
688             continue;
689         }
690         auto property = sceneSession->GetSessionProperty();
691         if (property == nullptr) {
692             continue;
693         }
694         bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
695             property->GetExtensionFlag();
696         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
697             sceneSession->SwitchFreeMultiWindow(enable);
698         }
699     }
700     WindowStyleType type = enable ?
701             WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
702     SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
703     return WSError::WS_OK;
704 }
705 
GetFreeMultiWindowEnableState(bool & enable)706 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
707 {
708     enable = systemConfig_.freeMultiWindowEnable_;
709     return WSError::WS_OK;
710 }
711 
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)712 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
713     const ContinueState& continueState)
714 {
715     TLOGI(WmsLogTag::DEFAULT, "Enter");
716     auto task = [this, token, continueState]() {
717         sptr <SceneSession> sceneSession = FindSessionByToken(token);
718         if (sceneSession == nullptr) {
719             TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
720             return WSError::WS_ERROR_INVALID_PARAM;
721         }
722         sceneSession->SetSessionInfoContinueState(continueState);
723         DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
724             static_cast<AAFwk::ContinueState>(continueState));
725         TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
726             sceneSession->GetPersistentId(), continueState);
727         return WSError::WS_OK;
728     };
729     return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
730 }
731 
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)732 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
733 {
734     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
735     if (item.IsBool()) {
736         if (mainConfig) {
737             systemConfig_.isSystemDecorEnable_ = item.boolValue_;
738         } else {
739             systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
740         }
741         bool decorEnable = item.boolValue_;
742         uint32_t support = 0;
743         std::vector<std::string> supportedModes;
744         item = decorConfig["supportedMode"];
745         if (item.IsStrings()) {
746             supportedModes = *item.stringsValue_;
747         }
748         for (auto mode : supportedModes) {
749             if (mode == "fullscreen") {
750                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
751             } else if (mode == "floating") {
752                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
753             } else if (mode == "pip") {
754                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
755             } else if (mode == "split") {
756                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
757                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
758             } else {
759                 WLOGFW("Invalid supporedMode");
760                 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
761                 break;
762             }
763         }
764         if (mainConfig && item.IsStrings()) {
765             systemConfig_.decorWindowModeSupportType_ = support;
766         }
767         if (!mainConfig && item.IsStrings()) {
768             systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
769         }
770     }
771 }
772 
AddAlphaToColor(float alpha,std::string & color)773 static void AddAlphaToColor(float alpha, std::string& color)
774 {
775     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
776         return;
777     }
778 
779     uint32_t alphaValue = 0xFF * alpha;
780     std::stringstream ss;
781     ss << std::hex << alphaValue;
782     std::string strAlpha = ss.str();
783     if (strAlpha.size() == 1) {
784         strAlpha.append(1, '0');
785     }
786 
787     color.insert(1, strAlpha);
788 }
789 
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)790 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
791 {
792     return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
793         (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
794         AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
795 }
796 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)797 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
798 {
799     AppWindowSceneConfig config;
800     // config corner radius
801     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
802     if (item.IsMap()) {
803         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
804             appWindowSceneConfig_ = config;
805         }
806     }
807 
808     // config shadow
809     item = effectConfig["appWindows"]["shadow"]["focused"];
810     if (item.IsMap()) {
811         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
812             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
813         }
814     }
815 
816     item = effectConfig["appWindows"]["shadow"]["unfocused"];
817     if (item.IsMap()) {
818         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
819             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
820         }
821     }
822 
823     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
824     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
825 
826     WLOGFI("Config window effect successfully");
827 }
828 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)829 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
830 {
831     std::map<std::string, float> stringToCornerRadius = {
832         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
833         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
834     };
835 
836     if (item.IsString()) {
837         auto value = item.stringValue_;
838         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
839             out = stringToCornerRadius[value];
840             return true;
841         }
842     }
843     return false;
844 }
845 
SetEnableInputEvent(bool enabled)846 void SceneSessionManager::SetEnableInputEvent(bool enabled)
847 {
848     TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
849     enableInputEvent_ = enabled;
850 }
851 
IsInputEventEnabled()852 bool SceneSessionManager::IsInputEventEnabled()
853 {
854     return enableInputEvent_;
855 }
856 
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)857 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
858 {
859     for (const auto& persistentId : alivePersistentIds_) {
860         auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
861         if (it != recoveredPersistentIds.end()) {
862             continue;
863         }
864         auto sceneSession = GetSceneSession(persistentId);
865         if (sceneSession == nullptr) {
866             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
867             continue;
868         }
869         if (sceneSession->IsRecovered()) {
870             TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
871             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
872             EraseSceneSessionAndMarkDirtyLocked(persistentId);
873         }
874     }
875 }
876 
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)877 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
878 {
879     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
880         recoveredPersistentIds.size(), currentUserId_.load());
881 
882     auto task = [this, recoveredPersistentIds]() {
883         ClearUnrecoveredSessions(recoveredPersistentIds);
884         std::list<AAFwk::SessionInfo> abilitySessionInfos;
885         for (const auto& persistentId : recoveredPersistentIds) {
886             if (failRecoveredPersistentIdSet_.count(persistentId)) {
887                 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
888                 continue;
889             }
890             auto sceneSession = GetSceneSession(persistentId);
891             if (sceneSession == nullptr) {
892                 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
893                 continue;
894             }
895             const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
896             if (!abilitySessionInfo) {
897                 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
898                 continue;
899             }
900             TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
901             abilitySessionInfos.emplace_back(*abilitySessionInfo);
902         }
903         std::vector<int32_t> unrecoverableSessionIds;
904         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
905             abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
906         TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
907             unrecoverableSessionIds.size());
908         for (const auto& sessionId : unrecoverableSessionIds) {
909             auto sceneSession = GetSceneSession(sessionId);
910             if (sceneSession == nullptr) {
911                 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
912                     sessionId);
913                 continue;
914             }
915             const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
916             if (!scnSessionInfo) {
917                 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
918                 continue;
919             }
920             TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
921             sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
922         }
923         RemoveFailRecoveredSession();
924     };
925     return taskScheduler_->PostAsyncTask(task);
926 }
927 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)928 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
929     WindowShadowConfig& outShadow)
930 {
931     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
932     if (item.IsString()) {
933         auto color = item.stringValue_;
934         uint32_t colorValue;
935         if (!ColorParser::Parse(color, colorValue)) {
936             return false;
937         }
938         outShadow.color_ = color;
939     }
940 
941     item = shadowConfig["offsetX"];
942     if (item.IsFloats()) {
943         auto offsetX = *item.floatsValue_;
944         if (offsetX.size() != 1) {
945             return false;
946         }
947         outShadow.offsetX_ = offsetX[0];
948     }
949 
950     item = shadowConfig["offsetY"];
951     if (item.IsFloats()) {
952         auto offsetY = *item.floatsValue_;
953         if (offsetY.size() != 1) {
954             return false;
955         }
956         outShadow.offsetY_ = offsetY[0];
957     }
958 
959     item = shadowConfig["alpha"];
960     if (item.IsFloats()) {
961         auto alpha = *item.floatsValue_;
962         if (alpha.size() != 1 ||
963             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
964             return false;
965         }
966         outShadow.alpha_ = alpha[0];
967     }
968 
969     item = shadowConfig["radius"];
970     if (item.IsFloats()) {
971         auto radius = *item.floatsValue_;
972         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
973             return false;
974         }
975         outShadow.radius_ = radius[0];
976     }
977 
978     return true;
979 }
980 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)981 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
982     KeyboardSceneAnimationConfig& config)
983 {
984     if (item.IsMap() && item.mapValue_->count("curve")) {
985         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
986         config.curveType_ = curveType;
987         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
988             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
989             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
990             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
991             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
992         }
993     }
994 
995     const WindowSceneConfig::ConfigItem& duration = item["duration"];
996     if (duration.IsInts()) {
997         auto numbers = *duration.intsValue_;
998         if (numbers.size() == 1) {
999             config.duration_ = static_cast<uint32_t>(numbers[0]);
1000         }
1001     }
1002 }
1003 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)1004 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
1005 {
1006     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
1007     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
1008 
1009     // config system animation
1010     const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
1011     systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
1012         {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
1013         appConfigIn.duration_);
1014     const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
1015     systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
1016         {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
1017         appConfigOut.duration_);
1018 }
1019 
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)1020 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
1021     KeyboardSceneAnimationConfig& animationOut)
1022 {
1023     if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
1024         TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
1025             "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
1026             systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
1027             systemConfig_.animationOut_.duration_);
1028         return;
1029     }
1030 
1031     // default animation curve params
1032     constexpr char CURVETYPE[] = "interpolatingSpring";
1033     constexpr float IN_CTRLX1 = 0.0f;
1034     constexpr float OUT_CTRLX1 = 4.0f;
1035     constexpr float CTRLY1 = 1.0f;
1036     constexpr float CTRLX2 = 342.0f;
1037     constexpr float CTRLY2 = 37.0f;
1038     constexpr uint32_t DURATION = 150;
1039     std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1040     std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
1041 
1042     // update system config for client
1043     systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1044     systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1045 
1046     // update app config for server
1047     animationIn.curveType_ = CURVETYPE;
1048     animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1049     animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1050     animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1051     animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1052     animationIn.duration_ = DURATION;
1053 
1054     animationOut.curveType_ = CURVETYPE;
1055     animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1056     animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1057     animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1058     animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1059     animationOut.duration_ = DURATION;
1060     TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
1061 }
1062 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1063 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1064 {
1065     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1066     if (item.IsMap() && item.mapValue_->count("curve")) {
1067         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1068         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1069         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1070             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1071             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1072             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1073             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1074         }
1075     }
1076     item = windowAnimationConfig["timing"]["duration"];
1077     if (item.IsInts() && item.intsValue_->size() == 1) {
1078         auto duration = *item.intsValue_;
1079         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1080     }
1081     item = windowAnimationConfig["scale"];
1082     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1083         auto scales = *item.floatsValue_;
1084         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1085         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1086     }
1087     item = windowAnimationConfig["rotation"];
1088     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1089         auto rotations = *item.floatsValue_;
1090         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1091         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1092         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1093         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1094     }
1095     item = windowAnimationConfig["translate"];
1096     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1097         auto translates = *item.floatsValue_;
1098         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1099         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1100     }
1101     item = windowAnimationConfig["opacity"];
1102     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1103         auto opacity = *item.floatsValue_;
1104         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1105     }
1106 }
1107 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1108 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1109 {
1110     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1111     auto item = configItem.GetProp("enable");
1112     if (item.IsBool()) {
1113         config.enabled_ = item.boolValue_;
1114     }
1115     item = configItem["timing"];
1116     if (item.IsMap() && item.mapValue_->count("curve")) {
1117         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1118     }
1119     item = configItem["timing"]["duration"];
1120     if (item.IsInts() && item.intsValue_->size() == 1) {
1121         config.duration_ = (*item.intsValue_)[0];
1122     }
1123     item = configItem["opacityStart"];
1124     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1125         config.opacityStart_ = (*item.floatsValue_)[0];
1126     }
1127     item = configItem["opacityEnd"];
1128     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1129         config.opacityEnd_ = (*item.floatsValue_)[0];
1130     }
1131 }
1132 
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1133 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1134     const WindowSceneConfig::ConfigItem& curveConfig)
1135 {
1136     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1137         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1138     static std::unordered_set<std::string> paramCurveSet = {
1139         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1140 
1141     std::string curveName = "easeOut";
1142     const auto& nameItem = curveConfig.GetProp("name");
1143     if (!nameItem.IsString()) {
1144         return {curveName, {}};
1145     }
1146 
1147     std::string name = nameItem.stringValue_;
1148     std::vector<float> curveParams;
1149 
1150     if (paramCurveSet.find(name) != paramCurveSet.end()) {
1151         curveName = name;
1152         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1153         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1154             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1155                 curveParams.begin());
1156         }
1157     } else {
1158         auto iter = curveSet.find(name);
1159         if (iter != curveSet.end()) {
1160             curveName = name;
1161         }
1162     }
1163 
1164     return {curveName, curveParams};
1165 }
1166 
ConfigWindowSizeLimits()1167 void SceneSessionManager::ConfigWindowSizeLimits()
1168 {
1169     const auto& config = WindowSceneConfig::GetConfig();
1170     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1171     if (item.IsMap()) {
1172         ConfigMainWindowSizeLimits(item);
1173     }
1174 
1175     item = config["subWindowSizeLimits"];
1176     if (item.IsMap()) {
1177         ConfigSubWindowSizeLimits(item);
1178     }
1179 }
1180 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1181 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1182 {
1183     auto item = mainWindowSizeConifg["miniWidth"];
1184     if (item.IsInts()) {
1185         auto numbers = *item.intsValue_;
1186         if (numbers.size() == 1) {
1187             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1188         }
1189     }
1190 
1191     item = mainWindowSizeConifg["miniHeight"];
1192     if (item.IsInts()) {
1193         auto numbers = *item.intsValue_;
1194         if (numbers.size() == 1) {
1195             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1196         }
1197     }
1198 }
1199 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1200 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1201 {
1202     auto item = subWindowSizeConifg["miniWidth"];
1203     if (item.IsInts()) {
1204         auto numbers = *item.intsValue_;
1205         if (numbers.size() == 1) {
1206             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1207         }
1208     }
1209 
1210     item = subWindowSizeConifg["miniHeight"];
1211     if (item.IsInts()) {
1212         auto numbers = *item.intsValue_;
1213         if (numbers.size() == 1) {
1214             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1215         }
1216     }
1217 }
1218 
ConfigSnapshotScale()1219 void SceneSessionManager::ConfigSnapshotScale()
1220 {
1221     const auto& config = WindowSceneConfig::GetConfig();
1222     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1223     if (item.IsFloats()) {
1224         auto snapshotScale = *item.floatsValue_;
1225         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1226             return;
1227         }
1228         snapshotScale_ = snapshotScale[0];
1229     }
1230 }
1231 
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1232 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1233 {
1234     TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1235     WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1236     if (item.IsInts() && item.intsValue_->size() == 1) {
1237         bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1238         appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1239         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1240             appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1241     }
1242 
1243     item = statusBarConfig["immersiveStatusBarBgColor"];
1244     if (item.IsString()) {
1245         auto color = item.stringValue_;
1246         uint32_t colorValue;
1247         if (!ColorParser::Parse(color, colorValue)) {
1248             return;
1249         }
1250         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1251         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1252             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1253     }
1254 
1255     item = statusBarConfig["immersiveStatusBarContentColor"];
1256     if (item.IsString()) {
1257         auto color = item.stringValue_;
1258         uint32_t colorValue;
1259         if (!ColorParser::Parse(color, colorValue)) {
1260             return;
1261         }
1262         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1263         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1264             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1265     }
1266 }
1267 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1268 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1269 {
1270     rootSceneContextWeak_ = contextWeak;
1271 }
1272 
GetRootSceneSession()1273 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1274 {
1275     auto task = [this]() -> sptr<RootSceneSession> {
1276         if (rootSceneSession_ != nullptr) {
1277             return rootSceneSession_;
1278         }
1279         system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1280         rootSceneSession_ = new RootSceneSession();
1281         rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1282         AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1283         return rootSceneSession_;
1284     };
1285 
1286     return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1287 }
1288 
GetRootSessionAvoidSessionRect(AvoidAreaType type)1289 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1290 {
1291     sptr<RootSceneSession> rootSession = GetRootSceneSession();
1292     if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1293         return {};
1294     }
1295     DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1296     std::vector<sptr<SceneSession>> sessionVector;
1297     switch (type) {
1298         case AvoidAreaType::TYPE_SYSTEM: {
1299             sessionVector = GetSceneSessionVectorByTypeAndDisplayId(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1300             break;
1301         }
1302         case AvoidAreaType::TYPE_KEYBOARD: {
1303             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
1304             break;
1305         }
1306         default: {
1307             TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1308             return {};
1309         }
1310     }
1311 
1312     for (auto& session : sessionVector) {
1313         if (!session->IsVisible()) {
1314             continue;
1315         }
1316         const WSRect rect = session->GetSessionRect();
1317         TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1318         return rect;
1319     }
1320     return {};
1321 }
1322 
GetSceneSession(int32_t persistentId)1323 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1324 {
1325     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1326     auto iter = sceneSessionMap_.find(persistentId);
1327     if (iter == sceneSessionMap_.end()) {
1328         WLOGFD("Error found scene session with id: %{public}d", persistentId);
1329         return nullptr;
1330     }
1331     return iter->second;
1332 }
1333 
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1334 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1335     const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1336 {
1337     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1338     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1339         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1340             sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1341             SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1342             mainSessions.push_back(sceneSession);
1343         }
1344     }
1345 }
1346 
GetMainSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,std::vector<sptr<SceneSession>> & mainSessions) const1347 void SceneSessionManager::GetMainSessionByAbilityInfo(const AbilityInfoBase& abilityInfo,
1348     std::vector<sptr<SceneSession>>& mainSessions) const
1349 {
1350     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1351     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1352         if (!sceneSession || !SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1353             continue;
1354         }
1355         if (sceneSession->GetSessionInfo().bundleName_ == abilityInfo.bundleName &&
1356             sceneSession->GetSessionInfo().moduleName_ == abilityInfo.moduleName &&
1357             sceneSession->GetSessionInfo().abilityName_ == abilityInfo.abilityName &&
1358             sceneSession->GetSessionInfo().appIndex_ == abilityInfo.appIndex) {
1359             mainSessions.push_back(sceneSession);
1360         }
1361     }
1362 }
1363 
GetSceneSessionByName(const ComparedSessionInfo & info)1364 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const ComparedSessionInfo& info)
1365 {
1366     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1367     for (const auto &item : sceneSessionMap_) {
1368         auto sceneSession = item.second;
1369         if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1370             sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1371             sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1372             continue;
1373         }
1374         if (info.isAtomicService_) {
1375             if ((sceneSession->GetSessionInfo().moduleName_.empty() ||
1376                 sceneSession->GetSessionInfo().moduleName_ == info.moduleName_) &&
1377                 (sceneSession->GetSessionInfo().abilityName_.empty() ||
1378                 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_)) {
1379                 return sceneSession;
1380             }
1381         } else if (sceneSession->GetSessionInfo().moduleName_ == info.moduleName_ &&
1382             sceneSession->GetSessionInfo().abilityName_ == info.abilityName_) {
1383             return sceneSession;
1384         }
1385     }
1386     return nullptr;
1387 }
1388 
GetSceneSessionByType(WindowType type)1389 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1390 {
1391     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1392     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1393         if (sceneSession && sceneSession->GetWindowType() == type) {
1394             return sceneSession;
1395         }
1396     }
1397     return nullptr;
1398 }
1399 
GetSceneSessionByBundleName(const std::string & bundleName)1400 sptr<SceneSession> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1401 {
1402     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1403     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1404         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1405             return sceneSession;
1406         }
1407     }
1408     return nullptr;
1409 }
1410 
GetSceneSessionVectorByTypeAndDisplayId(WindowType type,uint64_t displayId)1411 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByTypeAndDisplayId(
1412     WindowType type, uint64_t displayId)
1413 {
1414     if (displayId == DISPLAY_ID_INVALID) {
1415         TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1416         return {};
1417     }
1418     std::vector<sptr<SceneSession>> sceneSessionVector;
1419     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1420     for (const auto &item : sceneSessionMap_) {
1421         auto sceneSession = item.second;
1422         if (sceneSession->GetWindowType() == type &&
1423             sceneSession->GetSessionProperty() &&
1424             sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1425             sceneSessionVector.emplace_back(sceneSession);
1426         }
1427     }
1428 
1429     return sceneSessionVector;
1430 }
1431 
GetSceneSessionVectorByType(WindowType type)1432 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
1433 {
1434     std::vector<sptr<SceneSession>> sceneSessionVector;
1435     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1436     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1437         if (sceneSession->GetWindowType() == type) {
1438             sceneSessionVector.emplace_back(sceneSession);
1439         }
1440     }
1441     return sceneSessionVector;
1442 }
1443 
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1444 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1445     sptr<WindowSessionProperty> property)
1446 {
1447     if (property == nullptr) {
1448         TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1449         return WSError::WS_ERROR_NULLPTR;
1450     }
1451     if (sceneSession == nullptr) {
1452         TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1453         return WSError::WS_ERROR_NULLPTR;
1454     }
1455     auto parentPersistentId = property->GetParentPersistentId();
1456     sceneSession->SetParentPersistentId(parentPersistentId);
1457     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1458         auto parentSession = GetSceneSession(parentPersistentId);
1459         if (parentSession == nullptr) {
1460             TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1461             return WSError::WS_ERROR_NULLPTR;
1462         }
1463         parentSession->BindDialogSessionTarget(sceneSession);
1464         parentSession->BindDialogToParentSession(sceneSession);
1465         sceneSession->SetParentSession(parentSession);
1466         TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1467             sceneSession->GetPersistentId(), parentPersistentId);
1468     }
1469     return WSError::WS_OK;
1470 }
1471 
CreateSpecificSessionCallback()1472 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1473 {
1474     sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
1475     if (specificCb == nullptr) {
1476         WLOGFE("SpecificSessionCallback is nullptr");
1477         return nullptr;
1478     }
1479     specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1480         return this->RequestSceneSession(sessionInfo, property);
1481     };
1482     specificCb->onDestroy_ = [this](const int32_t persistentId) {
1483         return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1484     };
1485     specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1486         this->ClearDisplayStatusBarTemporarilyFlags();
1487     };
1488     specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1489         this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1490     };
1491     specificCb->onGetSceneSessionVectorByTypeAndDisplayId_ = [this](WindowType type, uint64_t displayId) {
1492         return this->GetSceneSessionVectorByTypeAndDisplayId(type, displayId);
1493     };
1494     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type) {
1495         return this->GetSceneSessionVectorByType(type);
1496     };
1497     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1498         this->UpdateAvoidArea(persistentId);
1499     };
1500     specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1501         return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1502     };
1503     specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1504         this->UpdateOccupiedAreaIfNeed(persistentId);
1505     };
1506     specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1507         this->NotifyWindowInfoChange(persistentId, type);
1508     };
1509     specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1510         this->NotifyMMIWindowPidChange(windowId, startMoving);
1511     };
1512     specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1513         this->NotifySessionTouchOutside(persistentId);
1514     };
1515     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1516         return this->GetAINavigationBarArea(displayId);
1517     };
1518     specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1519         this->OnOutsideDownEvent(x, y);
1520     };
1521     specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1522         return this->HandleSecureSessionShouldHide(sceneSession);
1523     };
1524     specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1525         this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1526     };
1527     specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1528         this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1529     };
1530     specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1531         this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1532     };
1533     specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1534         this->UpdateGestureBackEnabled(persistentId);
1535     };
1536     return specificCb;
1537 }
1538 
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1539 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1540 {
1541     TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1542     auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1543     if (isSkip) {
1544         if (it == skipSurfaceNodeIds_.end()) {
1545             skipSurfaceNodeIds_.push_back(surfaceNodeId);
1546         } else {
1547             return;
1548         }
1549     } else {
1550         if (it != skipSurfaceNodeIds_.end()) {
1551             skipSurfaceNodeIds_.erase(it);
1552         } else {
1553             return;
1554         }
1555     }
1556     rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1557 }
1558 
CreateKeyboardSessionCallback()1559 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1560 {
1561     sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1562         new (std::nothrow)KeyboardSession::KeyboardSessionCallback();
1563     if (keyboardCb == nullptr) {
1564         TLOGE(WmsLogTag::WMS_KEYBOARD, "KeyboardSessionCallback is nullptr");
1565         return keyboardCb;
1566     }
1567     keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1568         return this->GetSceneSession(persistentId);
1569     };
1570     keyboardCb->onGetFocusedSessionId_ = [this] {
1571         return this->GetFocusedSessionId();
1572     };
1573     keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1574 
1575     return keyboardCb;
1576 }
1577 
CheckWindowId(int32_t windowId,int32_t & pid)1578 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1579 {
1580     if (!SessionPermission::IsSystemCalling()) {
1581         TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1582         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1583     }
1584 
1585     auto task = [this, windowId, &pid]() -> WMError {
1586         pid = INVALID_PID;
1587         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1588         auto iter = sceneSessionMap_.find(windowId);
1589         if (iter == sceneSessionMap_.end()) {
1590             WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
1591             return WMError::WM_ERROR_INVALID_WINDOW;
1592         }
1593         auto sceneSession = iter->second;
1594         if (sceneSession == nullptr) {
1595             WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1596             return WMError::WM_ERROR_INVALID_WINDOW;
1597         }
1598         pid = sceneSession->GetCallingPid();
1599         WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1600         return WMError::WM_OK;
1601     };
1602     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1603 }
1604 
GetLockScreenZOrder()1605 uint32_t SceneSessionManager::GetLockScreenZOrder()
1606 {
1607     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1608     for (const auto& [persistentId, session] : sceneSessionMap_) {
1609         if (session && session->IsScreenLockWindow()) {
1610             TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: found window %{public}d", persistentId);
1611             return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
1612                 session->GetZOrder();
1613         }
1614     }
1615     TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
1616     return DEFAULT_LOCK_SCREEN_ZORDER;
1617 }
1618 
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)1619 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
1620     const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
1621 {
1622     std::ostringstream ss;
1623     ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
1624     return taskScheduler_->PostSyncTask([this, windowId, callingTokenId, &element, extensionAbilityType, &pid]() {
1625         pid = INVALID_PID;
1626         auto sceneSession = GetSceneSession(windowId);
1627         if (sceneSession == nullptr) {
1628             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
1629             return WMError::WM_ERROR_INVALID_WINDOW;
1630         }
1631         pid = sceneSession->GetCallingPid();
1632         if (!IsScreenLocked()) {
1633             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
1634             return WMError::WM_OK;
1635         }
1636         if (IsUserAuthPassed()) {
1637             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
1638             return WMError::WM_OK;
1639         }
1640         // 1. check window whether can show on main window
1641         if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
1642             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
1643             return WMError::WM_OK;
1644         }
1645         // 2. check permission
1646         if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
1647             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
1648                 callingTokenId);
1649             return WMError::WM_ERROR_INVALID_PERMISSION;
1650         }
1651         TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: IsShowOnLockScreen: The caller permission has granted");
1652         return WMError::WM_OK;
1653     }, ss.str());
1654 }
1655 
1656 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)1657 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
1658 {
1659     taskScheduler_->PostSyncTask([this, &windowIds]() {
1660         // check every window
1661         for (auto windowId : windowIds) {
1662             auto sceneSession = GetSceneSession(windowId);
1663             if (!sceneSession) {
1664                 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
1665                 continue;
1666             }
1667             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
1668             sceneSession->OnNotifyAboveLockScreen();
1669         }
1670         return WMError::WM_OK;
1671     }, __func__);
1672 }
1673 
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1674 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1675 {
1676     if (!isKeyboardPanelEnabled_) {
1677         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1678         return;
1679     }
1680     if (keyboardSession == nullptr) {
1681         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1682         return;
1683     }
1684     auto sessionProperty = keyboardSession->GetSessionProperty();
1685     if (sessionProperty == nullptr) {
1686         TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1687         return;
1688     }
1689     DisplayId displayId = sessionProperty->GetDisplayId();
1690     const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL);
1691     sptr<SceneSession> panelSession;
1692     if (panelVec.size() > 1) {
1693         TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1694         return;
1695     } else if (panelVec.size() == 1) {
1696         panelSession = panelVec.front();
1697         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1698     } else {
1699         SessionInfo panelInfo = {
1700             .bundleName_ = "SCBKeyboardPanel",
1701             .moduleName_ = "SCBKeyboardPanel",
1702             .abilityName_ = "SCBKeyboardPanel",
1703             .isSystem_ = true,
1704             .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1705             .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1706             .screenId_ = static_cast<uint64_t>(displayId),
1707             .isRotable_ = true,
1708         };
1709         static bool is2in1 = systemConfig_.uiType_ == UI_TYPE_PC;
1710         if (is2in1) {
1711             panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1712             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1713         } else {
1714             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1715         }
1716         panelSession = RequestSceneSession(panelInfo, nullptr);
1717         if (panelSession == nullptr) {
1718             TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1719             return;
1720         }
1721     }
1722     keyboardSession->BindKeyboardPanelSession(panelSession);
1723     panelSession->BindKeyboardSession(keyboardSession);
1724     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1725         panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1726 }
1727 
OnSCBSystemSessionBufferAvailable(WindowType type)1728 void SceneSessionManager::OnSCBSystemSessionBufferAvailable(WindowType type)
1729 {
1730     TLOGI(WmsLogTag::WMS_MULTI_USER, "In");
1731     if (type == WindowType::WINDOW_TYPE_KEYGUARD) {
1732         TLOGI(WmsLogTag::WMS_MULTI_USER, "On screen lock buffer available");
1733     }
1734 }
1735 
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1736 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1737     sptr<WindowSessionProperty> property)
1738 {
1739     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1740     sptr<SceneSession> sceneSession = nullptr;
1741     if (sessionInfo.isSystem_) {
1742         sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
1743         WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1744         if (sceneSession != nullptr &&
1745             static_cast<OHOS::Rosen::WindowType>(sessionInfo.windowType_) == WindowType::WINDOW_TYPE_KEYGUARD) {
1746             TLOGI(WmsLogTag::WMS_MULTI_USER, "Register screen lock buffer available");
1747             sceneSession->RegisterBufferAvailableCallback([this] {
1748                 this->OnSCBSystemSessionBufferAvailable(WindowType::WINDOW_TYPE_KEYGUARD);
1749             });
1750         }
1751     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1752         sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
1753         if (sceneSession != nullptr) {
1754             TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1755         }
1756     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1757         sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
1758         TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1759     } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1760         sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1761         sceneSession = new (std::nothrow) KeyboardSession(sessionInfo, specificCb, keyboardCb);
1762         CreateKeyboardPanelSession(sceneSession);
1763         TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1764     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1765         sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
1766         TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1767     } else {
1768         TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1769     }
1770     if (sceneSession != nullptr) {
1771         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1772         sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1773         sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1774             return this->GetAppForceLandscapeConfig(bundleName);
1775         });
1776         sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1777             this->UpdatePrivateStateAndNotify(persistentId);
1778         });
1779         sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1780             this->NotifyVisibleChange(persistentId);
1781         });
1782         sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
1783             return this->IsLastFrameLayoutFinished(isLayoutFinished);
1784         });
1785         sceneSession->SetIsAINavigationBarAvoidAreaValidFunc([this](const AvoidArea& avoidArea, int32_t sessionBottom) {
1786             return CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea, sessionBottom);
1787         });
1788         DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1789         GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
1790         sceneSession->SetAppDragResizeType(dragResizeType);
1791         TLOGI(WmsLogTag::WMS_ATTRIBUTE, "winId: %{public}d, displayId: %{public}" PRIu64,
1792             sceneSession->GetPersistentId(), sceneSession->GetSessionProperty()->GetDisplayId());
1793         sceneSession->SetSingleHandTransform(singleHandTransform_);
1794     }
1795     return sceneSession;
1796 }
1797 
GetEffectiveDragResizeType(DragResizeType & dragResizeType)1798 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
1799 {
1800     if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1801         return;
1802     }
1803     if (systemConfig_.freeMultiWindowSupport_) {
1804         dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
1805     } else {
1806         dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
1807     }
1808 }
1809 
SetGlobalDragResizeType(DragResizeType dragResizeType)1810 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
1811 {
1812     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1813     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1814         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1815         return WMError::WM_ERROR_INVALID_PERMISSION;
1816     }
1817     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1818     globalDragResizeType_ = dragResizeType;
1819     taskScheduler_->PostAsyncTask([this] {
1820         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1821         for (const auto& [_, sceneSession] : sceneSessionMap_) {
1822             if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1823                 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
1824                 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1825                 GetAppDragResizeType(bundleName, appDragResizeType);
1826                 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1827                     "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
1828                 sceneSession->SetAppDragResizeType(appDragResizeType);
1829             }
1830         }
1831     }, __func__);
1832     return WMError::WM_OK;
1833 }
1834 
GetGlobalDragResizeType(DragResizeType & dragResizeType)1835 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
1836 {
1837     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1838     dragResizeType = globalDragResizeType_;
1839     GetEffectiveDragResizeType(dragResizeType);
1840     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1841     return WMError::WM_OK;
1842 }
1843 
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)1844 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
1845 {
1846     TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1847         dragResizeType, bundleName.c_str());
1848     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1849         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1850         return WMError::WM_ERROR_INVALID_PERMISSION;
1851     }
1852     return SetAppDragResizeTypeInner(bundleName, dragResizeType);
1853 }
1854 
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)1855 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
1856 {
1857     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1858         dragResizeType, bundleName.c_str());
1859     if (bundleName.empty()) {
1860         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1861         return WMError::WM_ERROR_INVALID_PARAM;
1862     }
1863     std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
1864     appDragResizeTypeMap_[bundleName] = dragResizeType;
1865     GetAppDragResizeTypeInner(bundleName, dragResizeType);
1866     taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
1867         auto sceneSession = GetSceneSessionByBundleName(bundleName);
1868         if (sceneSession != nullptr) {
1869             TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1870                 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
1871             sceneSession->SetAppDragResizeType(dragResizeType);
1872         }
1873     }, __func__);
1874     return WMError::WM_OK;
1875 }
1876 
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)1877 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
1878 {
1879     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1880     return GetAppDragResizeTypeInner(bundleName, dragResizeType);
1881 }
1882 
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)1883 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
1884 {
1885     if (bundleName.empty()) {
1886         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1887         return WMError::WM_ERROR_INVALID_PARAM;
1888     }
1889     if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1890         TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
1891         dragResizeType = globalDragResizeType_;
1892         return WMError::WM_OK;
1893     }
1894     dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1895     if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
1896         dragResizeType = iter->second;
1897     }
1898     GetEffectiveDragResizeType(dragResizeType);
1899     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1900         dragResizeType, bundleName.c_str());
1901     return WMError::WM_OK;
1902 }
1903 
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)1904 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
1905 {
1906     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1907         auto session = GetSceneSession(sessionInfo.persistentId_);
1908         if (session != nullptr) {
1909             TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1910             return session;
1911         }
1912 
1913         if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1914             TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1915                 "abilityName: %{public}s, appIndex: %{public}d",
1916                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1917                 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1918             ComparedSessionInfo compareSessionInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_,
1919                 sessionInfo.appIndex_, sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1920             auto sceneSession = GetSceneSessionByName(compareSessionInfo);
1921             bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1922                 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1923             if (isSingleStart) {
1924                 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1925                     sessionInfo.persistentId_);
1926                 return sceneSession;
1927             }
1928         }
1929     }
1930     return nullptr;
1931 }
1932 
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1933 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1934     sptr<WindowSessionProperty> property)
1935 {
1936     const char* const where = __func__;
1937     auto task = [this, sessionInfo, property, where] {
1938         if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
1939             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1940             return session;
1941         }
1942         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
1943             "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1944             where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1945             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1946             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1947         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1948         if (sceneSession == nullptr) {
1949             TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1950             return sceneSession;
1951         }
1952         InitSceneSession(sceneSession, sessionInfo, property);
1953         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1954             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1955                 where, sceneSession->GetSessionInfo().ancoSceneState);
1956             bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1957             const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1958             if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1959                 TLOGNI(WmsLogTag::WMS_LIFE,
1960                     "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1961                     where, reusedSceneSession->GetPersistentId(),
1962                     reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1963                 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1964                 return reusedSceneSession;
1965             }
1966             if (isPreHandleSuccess) {
1967                 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1968                 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1969             }
1970         }
1971         {
1972             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1973             sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1974         }
1975         PerformRegisterInRequestSceneSession(sceneSession);
1976         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1977         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d, type: %{public}d, displayId: %{public}" PRIu64,
1978                where, sceneSession->GetPersistentId(), sceneSession->GetWindowType(),
1979                sceneSession->GetSessionProperty()->GetDisplayId());
1980         return sceneSession;
1981     };
1982     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1983 }
1984 
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)1985 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1986     const sptr<WindowSessionProperty>& property)
1987 {
1988     auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1989     DisplayId curDisplayId = DISPLAY_ID_INVALID;
1990     if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1991         curDisplayId = sessionInfo.screenId_;
1992     } else if (callerSession) {
1993         auto callerSessionProperty = callerSession->GetSessionProperty();
1994         if (callerSessionProperty) {
1995             curDisplayId = callerSessionProperty->GetDisplayId();
1996         }
1997     }
1998     auto sessionProperty = sceneSession->GetSessionProperty();
1999     if (sessionProperty) {
2000         sessionProperty->SetDisplayId(curDisplayId);
2001         sceneSession->SetScreenId(curDisplayId);
2002         TLOGI(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
2003             curDisplayId);
2004     }
2005     sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
2006     sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
2007     if (sessionInfo.isSystem_) {
2008         sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
2009         sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
2010         auto rootContext = rootSceneContextWeak_.lock();
2011         sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
2012     } else {
2013         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
2014             "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
2015             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2016             sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
2017     }
2018     RegisterSessionExceptionFunc(sceneSession);
2019     // Skip FillSessionInfo when atomicService free-install start.
2020     if (!IsAtomicServiceFreeInstall(sessionInfo)) {
2021         FillSessionInfo(sceneSession);
2022     }
2023     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
2024     if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
2025         sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
2026     }
2027     sceneSession->SetSystemConfig(systemConfig_);
2028     sceneSession->SetSnapshotScale(snapshotScale_);
2029     UpdateParentSessionForDialog(sceneSession, property);
2030     std::string key = sessionInfo.bundleName_ + "_" + sessionInfo.moduleName_ + "_" + sessionInfo.abilityName_ + "_" +
2031         std::to_string(sessionInfo.appIndex_);
2032     if (sessionLockedStateCacheSet_.find(key) != sessionLockedStateCacheSet_.end()) {
2033         sceneSession->NotifySessionLockStateChange(true);
2034     }
2035 }
2036 
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)2037 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
2038 {
2039     sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
2040     if (info == nullptr) {
2041         WLOGFE("new info failed");
2042         return;
2043     }
2044     info->action_ = action;
2045     info->abilityName_ = sessionInfo.abilityName_;
2046     info->bundleName_ = sessionInfo.bundleName_;
2047     info->toScreenId_ = sessionInfo.screenId_;
2048     info->fromScreenId_ = fromScreenId;
2049     ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
2050     WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
2051         info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
2052 }
2053 
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)2054 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
2055 {
2056     RegisterSessionSnapshotFunc(sceneSession);
2057     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
2058     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
2059     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
2060     RegisterGetStateFromManagerFunc(sceneSession);
2061     RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
2062     RegisterAcquireRotateAnimationConfigFunc(sceneSession);
2063 }
2064 
UpdateSceneSessionWant(const SessionInfo & sessionInfo)2065 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
2066 {
2067     if (sessionInfo.persistentId_ != 0) {
2068         auto session = GetSceneSession(sessionInfo.persistentId_);
2069         if (session != nullptr && sessionInfo.want != nullptr) {
2070             TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
2071             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
2072                 session->SetSessionInfoWant(sessionInfo.want);
2073                 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
2074             } else {
2075                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
2076             }
2077         } else {
2078             TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
2079                 session == nullptr, sessionInfo.persistentId_);
2080         }
2081     } else {
2082         TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
2083     }
2084 }
2085 
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2086 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2087 {
2088     if (session != nullptr) {
2089         if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2090             FillSessionInfo(session);
2091             if (CheckCollaboratorType(session->GetCollaboratorType())) {
2092                 PreHandleCollaborator(session, persistentId);
2093             }
2094         }
2095     }
2096 }
2097 
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)2098 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
2099 {
2100     sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
2101     if (abilitySessionInfo == nullptr) {
2102         WLOGFE("abilitySessionInfo is nullptr");
2103         return nullptr;
2104     }
2105     auto sessionInfo = scnSession->GetSessionInfo();
2106     sptr<ISession> iSession(scnSession);
2107     abilitySessionInfo->sessionToken = iSession->AsObject();
2108     abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2109         std::chrono::system_clock::now()).time_since_epoch().count());
2110     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2111     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2112         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2113     abilitySessionInfo->persistentId = scnSession->GetPersistentId();
2114     abilitySessionInfo->requestCode = sessionInfo.requestCode;
2115     abilitySessionInfo->resultCode = sessionInfo.resultCode;
2116     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2117     abilitySessionInfo->startSetting = sessionInfo.startSetting;
2118     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2119     abilitySessionInfo->userId = currentUserId_;
2120     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2121     abilitySessionInfo->processOptions = sessionInfo.processOptions;
2122     abilitySessionInfo->tmpSpecifiedId = sessionInfo.specifiedId;
2123     if (sessionInfo.want != nullptr) {
2124         abilitySessionInfo->want = *sessionInfo.want;
2125     } else {
2126         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2127             sessionInfo.moduleName_);
2128     }
2129     int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2130     bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2131     if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2132         TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2133             appIndex, sessionInfo.appIndex_);
2134     }
2135     if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2136         TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2137         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2138     }
2139     auto sessionProperty = scnSession->GetSessionProperty();
2140     if (sessionProperty) {
2141         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2142             static_cast<int>(sessionProperty->GetDisplayId()));
2143     }
2144     if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2145         sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2146         abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2147     } else {
2148         TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2149     }
2150     return abilitySessionInfo;
2151 }
2152 
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2153 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2154 {
2155     if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2156         isPrepareTerminate = false;
2157         TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2158         return WSError::WS_OK;
2159     }
2160     auto sceneSession = GetSceneSession(persistentId);
2161     if (sceneSession == nullptr) {
2162         TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2163         isPrepareTerminate = false;
2164         return WSError::WS_ERROR_NULLPTR;
2165     }
2166     auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2167     if (sceneSessionInfo == nullptr) {
2168         TLOGE(WmsLogTag::WMS_MAIN, "sceneSessionInfo is null, Id:%{public}d", persistentId);
2169         isPrepareTerminate = false;
2170         return WSError::WS_ERROR_NULLPTR;
2171     }
2172     auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2173         PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2174     TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2175         "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2176     return WSError::WS_OK;
2177 }
2178 
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)2179 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
2180 {
2181     wptr<SceneSession> weakSceneSession(sceneSession);
2182     auto task = [this, weakSceneSession, isNewActive]() {
2183         sptr<SceneSession> scnSession = weakSceneSession.promote();
2184         if (scnSession == nullptr) {
2185             TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2186             return WSError::WS_ERROR_NULLPTR;
2187         }
2188         auto persistentId = scnSession->GetPersistentId();
2189         if (!Session::IsScbCoreEnabled()) {
2190             scnSession->SetForegroundInteractiveStatus(true);
2191         }
2192         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2193         TLOGI(WmsLogTag::WMS_MAIN,
2194             "Request active id:%{public}d, system:%{public}u, isNewActive:%{public}d, specifiedId:%{public}d",
2195             persistentId, scnSession->GetSessionInfo().isSystem_,
2196             isNewActive, scnSession->GetSessionInfo().specifiedId);
2197         if (!GetSceneSession(persistentId)) {
2198             TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2199             return WSError::WS_ERROR_INVALID_SESSION;
2200         }
2201         auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
2202         if (ret == WSError::WS_OK) {
2203             scnSession->SetExitSplitOnBackground(false);
2204         }
2205         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
2206         return ret;
2207     };
2208     std::string taskName = "RequestSceneSessionActivation:PID:" +
2209         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2210     taskScheduler_->PostAsyncTask(task, taskName);
2211     return WSError::WS_OK;
2212 }
2213 
IsKeyboardForeground()2214 bool SceneSessionManager::IsKeyboardForeground()
2215 {
2216     bool isKeyboardForeground = false;
2217     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2218     for (const auto &item : sceneSessionMap_) {
2219         auto sceneSession = item.second;
2220         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2221             isKeyboardForeground = sceneSession->IsSessionForeground();
2222             break;
2223         }
2224     }
2225 
2226     return isKeyboardForeground;
2227 }
2228 
RequestInputMethodCloseKeyboard(const int32_t persistentId)2229 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
2230 {
2231     auto sceneSession = GetSceneSession(persistentId);
2232     if (sceneSession == nullptr) {
2233         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
2234         return;
2235     }
2236     // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
2237     if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
2238         !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
2239         TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
2240             persistentId, sceneSession->GetSessionState());
2241         sceneSession->RequestHideKeyboard(true);
2242     }
2243 }
2244 
StartUIAbilityBySCB(sptr<SceneSession> & scnSession)2245 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
2246 {
2247     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2248     if (abilitySessionInfo == nullptr) {
2249         return ERR_NULL_OBJECT;
2250     }
2251     return StartUIAbilityBySCB(abilitySessionInfo);
2252 }
2253 
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)2254 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
2255 {
2256     bool isColdStart = false;
2257     return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
2258 }
2259 
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession> & scnSession,bool visibility)2260 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
2261 {
2262     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2263     if (abilitySessionInfo == nullptr) {
2264         return ERR_NULL_OBJECT;
2265     }
2266     return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
2267 }
2268 
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive)2269 WSError SceneSessionManager::RequestSceneSessionActivationInner(
2270     sptr<SceneSession>& scnSession, bool isNewActive)
2271 {
2272     auto persistentId = scnSession->GetPersistentId();
2273     RequestInputMethodCloseKeyboard(persistentId);
2274     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2275         scnSession->SetIsStarting(true);
2276         scnSession->SetStartingBeforeVisible(true);
2277     }
2278     if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
2279         if (Session::IsScbCoreEnabled()) {
2280             if (scnSession->IsVisibleForeground()) {
2281                 RequestSessionFocusImmediately(persistentId);
2282             } else {
2283                 PostProcessFocusState state = { true, true, FocusChangeReason::SCB_START_APP };
2284                 scnSession->SetPostProcessFocusState(state);
2285             }
2286         } else {
2287             RequestSessionFocusImmediately(persistentId);
2288         }
2289     }
2290     if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2291         FillSessionInfo(scnSession);
2292         if (!PreHandleCollaborator(scnSession, persistentId)) {
2293             TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
2294                 persistentId, scnSession->GetSessionInfo().ancoSceneState);
2295             scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
2296             return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
2297         }
2298     }
2299     auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2300     if (!scnSessionInfo) {
2301         TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
2302         return WSError::WS_ERROR_NULLPTR;
2303     }
2304     scnSession->NotifyActivation();
2305     scnSessionInfo->isNewWant = isNewActive;
2306     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2307         scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
2308         scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
2309     }
2310     TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
2311         "module: %{public}s, uri: %{public}s, appIndex: %{public}d, tmpSpecifiedId:%{public}d", persistentId,
2312         scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
2313         scnSessionInfo->want.GetElement().GetBundleName().c_str(),
2314         scnSessionInfo->want.GetElement().GetModuleName().c_str(),
2315         scnSessionInfo->want.GetElement().GetURI().c_str(),
2316         scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0),
2317         scnSessionInfo->tmpSpecifiedId);
2318     int32_t errCode = ERR_OK;
2319     bool isColdStart = false;
2320     bool isAppSupportPhoneInPc = false;
2321     auto sessionProperty = scnSession->GetSessionProperty();
2322     if (sessionProperty != nullptr) {
2323         isAppSupportPhoneInPc = sessionProperty->GetIsAppSupportPhoneInPc();
2324     }
2325     if (systemConfig_.backgroundswitch == false || isAppSupportPhoneInPc) {
2326         TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
2327             static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2328         errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2329     } else {
2330         TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
2331             isNewActive, scnSession->GetSessionState());
2332         if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
2333             scnSession->GetSessionState() == SessionState::STATE_END) {
2334             TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
2335                 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2336             errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2337         } else {
2338             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
2339             scnSession->NotifySessionForeground(1, true);
2340         }
2341     }
2342     auto sessionInfo = scnSession->GetSessionInfo();
2343     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2344         WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
2345     }
2346     NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
2347 
2348     if (errCode != ERR_OK) {
2349         TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
2350         scnSession->NotifySessionExceptionInner(scnSessionInfo, true, false, true);
2351         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
2352             startUIAbilityErrorFunc_(
2353                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
2354         }
2355     }
2356     if (isColdStart) {
2357         TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
2358             scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
2359         scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
2360         scnSession->ResetSessionConnectState();
2361         scnSession->ResetIsActive();
2362     }
2363     return WSError::WS_OK;
2364 }
2365 
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)2366 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
2367     sptr<AAFwk::SessionInfo>& scnSessionInfo)
2368 {
2369     if (scnSession == nullptr || scnSessionInfo == nullptr) {
2370         return;
2371     }
2372     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2373         NotifyLoadAbility(scnSession->GetCollaboratorType(),
2374             scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
2375         NotifyUpdateSessionInfo(scnSession);
2376         NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2377         scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2378     }
2379 }
2380 
InitSnapshotCache()2381 void SceneSessionManager::InitSnapshotCache()
2382 {
2383     const static std::string invalidUitype = "";
2384     const static std::unordered_map<std::string, std::size_t> SNAPSHOT_CACHE_CAPACITY_MAP = {
2385         {UI_TYPE_PC,    MAX_SNAPSHOT_IN_RECENT_PC},
2386         {UI_TYPE_PAD,   MAX_SNAPSHOT_IN_RECENT_PAD},
2387         {UI_TYPE_PHONE, MAX_SNAPSHOT_IN_RECENT_PHONE},
2388         {invalidUitype, MAX_SNAPSHOT_IN_RECENT_PHONE},
2389     };
2390 
2391     auto uiType = systemConfig_.uiType_;
2392     snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(invalidUitype);
2393     if (SNAPSHOT_CACHE_CAPACITY_MAP.find(uiType) != SNAPSHOT_CACHE_CAPACITY_MAP.end()) {
2394         snapshotCapacity_ = SNAPSHOT_CACHE_CAPACITY_MAP.at(systemConfig_.uiType_);
2395     }
2396     TLOGI(WmsLogTag::WMS_PATTERN, "type: %{public}s, capacity: %{public}u",
2397         systemConfig_.uiType_.c_str(), snapshotCapacity_);
2398     snapshotLRUCache_ = std::make_unique<LRUCache>(snapshotCapacity_);
2399 }
2400 
PutSnapshotToCache(int32_t persistentId)2401 void SceneSessionManager::PutSnapshotToCache(int32_t persistentId)
2402 {
2403     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2404     if (int32_t removedCacheId = snapshotLRUCache_->Put(persistentId);
2405         removedCacheId != UNDEFINED_REMOVED_KEY) {
2406         if (auto removedCacheSession = GetSceneSession(removedCacheId)) {
2407             removedCacheSession->ResetSnapshot();
2408         } else {
2409             TLOGW(WmsLogTag::WMS_PATTERN, "removedCacheSession:%{public}d nullptr", removedCacheId);
2410         }
2411     }
2412 }
2413 
VisitSnapshotFromCache(int32_t persistentId)2414 void SceneSessionManager::VisitSnapshotFromCache(int32_t persistentId)
2415 {
2416     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2417     if (!snapshotLRUCache_->Visit(persistentId)) {
2418         TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d not in cache", persistentId);
2419     }
2420 }
2421 
RemoveSnapshotFromCache(int32_t persistentId)2422 void SceneSessionManager::RemoveSnapshotFromCache(int32_t persistentId)
2423 {
2424     TLOGD(WmsLogTag::WMS_PATTERN, "session:%{public}d", persistentId);
2425     snapshotLRUCache_->Remove(persistentId);
2426     if (auto sceneSession = GetSceneSession(persistentId)) {
2427         sceneSession->ResetSnapshot();
2428     }
2429 }
2430 
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)2431 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2432     const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2433 {
2434     wptr<SceneSession> weakSceneSession(sceneSession);
2435     auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
2436         auto scnSession = weakSceneSession.promote();
2437         if (scnSession == nullptr) {
2438             TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
2439             return WSError::WS_ERROR_NULLPTR;
2440         }
2441         auto persistentId = scnSession->GetPersistentId();
2442         TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2443             "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2444             persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2445         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2446         scnSession->SetActive(false);
2447 
2448         if (isToDesktop) {
2449             auto info = scnSession->GetSessionInfo();
2450             info.callerToken_ = nullptr;
2451             info.callingTokenId_ = 0;
2452             scnSession->SetSessionInfo(info);
2453         }
2454 
2455         scnSession->SetSaveSnapshotCallback([this, persistentId]() {
2456             this->PutSnapshotToCache(persistentId);
2457         });
2458 
2459         scnSession->BackgroundTask(isSaveSnapshot);
2460         if (!GetSceneSession(persistentId)) {
2461             TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2462             return WSError::WS_ERROR_INVALID_SESSION;
2463         }
2464         if (persistentId == brightnessSessionId_) {
2465             UpdateBrightness(focusedSessionId_);
2466         }
2467         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2468         if (!scnSessionInfo) {
2469             TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2470             return WSError::WS_ERROR_NULLPTR;
2471         }
2472         bool isPcAppInpad = false;
2473         bool isAppSupportPhoneInPc = false;
2474         auto property = scnSession->GetSessionProperty();
2475         if (property) {
2476             isPcAppInpad = property->GetIsPcAppInPad();
2477             isAppSupportPhoneInPc = property->GetIsAppSupportPhoneInPc();
2478         }
2479         if ((systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || isPcAppInpad) {
2480             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2481             scnSession->NotifySessionBackground(1, true, true);
2482         } else {
2483             TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2484                 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2485             if (!isDelegator) {
2486                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2487             } else {
2488                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2489             }
2490         }
2491 
2492         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2493             auto sessionInfo = scnSession->GetSessionInfo();
2494             WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2495         }
2496         return WSError::WS_OK;
2497     };
2498     std::string taskName = "RequestSceneSessionBackground:PID:" +
2499         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2500     taskScheduler_->PostAsyncTask(task, taskName);
2501     return WSError::WS_OK;
2502 }
2503 
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2504 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2505 {
2506     wptr<SceneSession> weakSceneSession(sceneSession);
2507     auto task = [this, weakSceneSession, interactive]() {
2508         auto scnSession = weakSceneSession.promote();
2509         if (scnSession == nullptr) {
2510             WLOGFE("session is nullptr");
2511             return;
2512         }
2513         auto persistentId = scnSession->GetPersistentId();
2514         WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2515         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2516         if (!GetSceneSession(persistentId)) {
2517             WLOGFE("session is invalid with %{public}d", persistentId);
2518             return;
2519         }
2520         scnSession->NotifyForegroundInteractiveStatus(interactive);
2521     };
2522 
2523     taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2524 }
2525 
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)2526 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2527 {
2528     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2529     if (scnSession == nullptr) {
2530         TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2531         return WSError::WS_ERROR_NULLPTR;
2532     }
2533     if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2534         TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2535         auto dialogVec = scnSession->GetDialogVector();
2536         for (auto dialog : dialogVec) {
2537             if (dialog == nullptr) {
2538                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2539                 continue;
2540             }
2541             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2542             if (sceneSession == nullptr) {
2543                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2544                 return WSError::WS_ERROR_INVALID_SESSION;
2545             }
2546             WindowDestroyNotifyVisibility(sceneSession);
2547             dialog->NotifyDestroy();
2548             dialog->Disconnect();
2549 
2550             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2551             if (dialogSceneSession != nullptr) {
2552                 dialogSceneSession->ClearSpecificSessionCbMap();
2553             }
2554             {
2555                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2556                 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2557                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2558                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2559             }
2560         }
2561         scnSession->ClearDialogVector();
2562         return WSError::WS_OK;
2563     }
2564     return WSError::WS_ERROR_INVALID_SESSION;
2565 }
2566 
DestroySubSession(const sptr<SceneSession> & sceneSession)2567 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2568 {
2569     if (sceneSession == nullptr) {
2570         TLOGW(WmsLogTag::WMS_SUB, "sceneSession is nullptr");
2571         return;
2572     }
2573     for (const auto& elem : sceneSession->GetSubSession()) {
2574         if (elem != nullptr) {
2575             const auto& persistentId = elem->GetPersistentId();
2576             TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2577             DestroyAndDisconnectSpecificSessionInner(persistentId);
2578         }
2579     }
2580 }
2581 
DestroyToastSession(const sptr<SceneSession> & sceneSession)2582 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2583 {
2584     if (sceneSession == nullptr) {
2585         TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2586         return;
2587     }
2588     for (const auto& elem : sceneSession->GetToastSession()) {
2589         if (elem != nullptr) {
2590             const auto& persistentId = elem->GetPersistentId();
2591             TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2592             DestroyAndDisconnectSpecificSessionInner(persistentId);
2593         }
2594     }
2595 }
2596 
BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t fingerId,int32_t action,int32_t wid)2597 void SceneSessionManager::BuildCancelPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
2598                                                   int32_t fingerId, int32_t action, int32_t wid)
2599 {
2600     if (pointerEvent == nullptr) {
2601         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is null, wid:%{public}d fingerId:%{public}d action:%{public}d",
2602                   wid, fingerId, action);
2603         return;
2604     }
2605     pointerEvent->SetId(CANCEL_POINTER_ID);
2606     pointerEvent->SetTargetWindowId(wid);
2607     pointerEvent->SetPointerId(fingerId);
2608     pointerEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_CANCEL);
2609     MMI::PointerEvent::PointerItem item;
2610     item.SetPointerId(fingerId);
2611     pointerEvent->AddPointerItem(item);
2612     if (action == MMI::PointerEvent::POINTER_ACTION_DOWN) {
2613         pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN);
2614     } else {
2615         pointerEvent->SetSourceType(MMI::PointerEvent::SOURCE_TYPE_MOUSE);
2616     }
2617 }
2618 
SendCancelEventBeforeEraseSession(const sptr<SceneSession> & sceneSession)2619 void SceneSessionManager::SendCancelEventBeforeEraseSession(const sptr<SceneSession>& sceneSession)
2620 {
2621     auto task = [this, needCancelEventSceneSession = sceneSession] {
2622         if (needCancelEventSceneSession == nullptr) {
2623             TLOGI(WmsLogTag::WMS_EVENT, "scenesession is nullptr, needn't send cancel event");
2624             return;
2625         }
2626         auto wid = needCancelEventSceneSession->GetPersistentId();
2627         if (needCancelEventSceneSession->GetMousePointerDownEventStatus()) {
2628             std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2629             BuildCancelPointerEvent(pointerEvent, 1, MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN, wid);
2630             TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send mouse cancel. wid:%{public}d", wid);
2631             needCancelEventSceneSession->SetMousePointerDownEventStatus(false);
2632             needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2633         }
2634         std::unordered_set<int32_t> fingerPointerDownStatusList = needCancelEventSceneSession->GetFingerPointerDownStatusList();
2635         if (fingerPointerDownStatusList.empty()) {
2636             return;
2637         }
2638         for (auto fingerId : fingerPointerDownStatusList) {
2639             std::shared_ptr<MMI::PointerEvent> pointerEvent = MMI::PointerEvent::Create();
2640             BuildCancelPointerEvent(pointerEvent, fingerId, MMI::PointerEvent::POINTER_ACTION_DOWN, wid);
2641             TLOGI(WmsLogTag::WMS_EVENT, "erasing sceneSession need send touch cancel. wid:%{public}d fingerId:%{public}d",
2642                   wid, fingerId);
2643             needCancelEventSceneSession->SendPointerEventToUI(pointerEvent);
2644             needCancelEventSceneSession->RemoveFingerPointerDownStatus(fingerId);
2645         }
2646     };
2647     mainHandler_->PostTask(std::move(task), "wms:sendCancelBeforeEraseSession", 0, AppExecFwk::EventQueue::Priority::VIP);
2648 }
2649 
EraseSceneSessionMapById(int32_t persistentId)2650 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2651 {
2652     auto sceneSession = GetSceneSession(persistentId);
2653     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2654     EraseSceneSessionAndMarkDirtyLocked(persistentId);
2655     systemTopSceneSessionMap_.erase(persistentId);
2656     nonSystemFloatSceneSessionMap_.erase(persistentId);
2657     SendCancelEventBeforeEraseSession(sceneSession);
2658 }
2659 
2660 /**
2661  * if visible session is erased, mark dirty
2662  * lock-free
2663  */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2664 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2665 {
2666     // get scene session lock-free
2667     auto iter = sceneSessionMap_.find(persistentId);
2668     if (iter == sceneSessionMap_.end()) {
2669         TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2670         return;
2671     }
2672     sptr<SceneSession> sceneSession = iter->second;
2673     if (sceneSession != nullptr && sceneSession->IsVisible()) {
2674         sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2675     }
2676     sceneSessionMap_.erase(persistentId);
2677 }
2678 
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean)2679 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2680     bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2681 {
2682     auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2683         needRemoveSession, isSaveSnapshot, isForceClean]() {
2684         auto scnSession = weakSceneSession.promote();
2685         if (scnSession == nullptr) {
2686             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2687             return WSError::WS_ERROR_NULLPTR;
2688         }
2689         auto persistentId = scnSession->GetPersistentId();
2690         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2691         RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2692         avoidAreaListenerSessionSet_.erase(persistentId);
2693         DestroyDialogWithMainWindow(scnSession);
2694         DestroyToastSession(scnSession);
2695         DestroySubSession(scnSession); // destroy sub session by destruction
2696         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2697             " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2698         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2699         WindowDestroyNotifyVisibility(scnSession);
2700         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2701         scnSession->SetRemoveSnapshotCallback([this, persistentId]() {
2702             this->RemoveSnapshotFromCache(persistentId);
2703         });
2704         scnSession->DisconnectTask(false, isSaveSnapshot);
2705         if (!GetSceneSession(persistentId)) {
2706             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2707             return WSError::WS_ERROR_INVALID_SESSION;
2708         }
2709         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2710         if (!scnSessionInfo) {
2711             return WSError::WS_ERROR_NULLPTR;
2712         }
2713         scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2714         ResetSceneSessionInfoWant(scnSessionInfo);
2715         return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2716     };
2717     std::string taskName = "RequestSceneSessionDestruction:PID:" +
2718         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2719     taskScheduler_->PostAsyncTask(task, taskName);
2720     return WSError::WS_OK;
2721 }
2722 
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)2723 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
2724 {
2725     if (sceneSessionInfo->resultCode == -1) {
2726         AAFwk::Want want;
2727         std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2728         want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2729         sceneSessionInfo->want = std::move(want);
2730         TLOGI(WmsLogTag::WMS_MAIN, "keySessionId: %{public}s", keySessionId.c_str());
2731     }
2732 }
2733 
ResetWant(sptr<SceneSession> & sceneSession)2734 void SceneSessionManager::ResetWant(sptr<SceneSession>& sceneSession)
2735 {
2736     auto& sessionInfo = sceneSession->GetSessionInfo();
2737     if (sessionInfo.want != nullptr) {
2738         const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2739         const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2740         const auto& keySessionId = sessionInfo.want->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2741         auto want = std::make_shared<AAFwk::Want>();
2742         if (want != nullptr) {
2743             AppExecFwk::ElementName element;
2744             element.SetBundleName(bundleName);
2745             element.SetAbilityName(abilityName);
2746             want->SetElement(element);
2747             want->SetBundle(bundleName);
2748             if (!keySessionId.empty()) {
2749                 want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2750             }
2751             sceneSession->SetSessionInfoWant(want);
2752         }
2753     }
2754 }
2755 
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession,const bool isForceClean)2756 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& scnSession,
2757     sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2758 {
2759     auto persistentId = scnSession->GetPersistentId();
2760     TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}u",
2761         persistentId,
2762         static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2763     if (isForceClean) {
2764         AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2765     } else {
2766         AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2767     }
2768     scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2769     if (needRemoveSession) {
2770         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2771             NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2772         }
2773         EraseSceneSessionMapById(persistentId);
2774     } else {
2775         // if terminate, reset want. so start from recent, start a new one.
2776         TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2777         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2778             scnSession->SetSessionInfoWant(nullptr);
2779         }
2780         ResetWant(scnSession);
2781         scnSession->ResetSessionInfoResultCode();
2782     }
2783     if (listenerController_ != nullptr) {
2784         NotifySessionForCallback(scnSession, needRemoveSession);
2785     }
2786     scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2787     return WSError::WS_OK;
2788 }
2789 
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)2790 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2791     const sptr<SceneSession>& sceneSession)
2792 {
2793     if (sceneSession == nullptr || sessionStage == nullptr) {
2794         TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2795         return;
2796     }
2797 
2798     auto remoteObject = sessionStage->AsObject();
2799     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2800     if (windowDeath_ == nullptr) {
2801         TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2802         return;
2803     }
2804     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2805         TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2806         return;
2807     }
2808     WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2809 }
2810 
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)2811 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2812 {
2813     auto task = [this, remoteObject]() {
2814         auto iter = remoteObjectMap_.find(remoteObject);
2815         if (iter == remoteObjectMap_.end()) {
2816             WLOGFE("Invalid remoteObject");
2817             return;
2818         }
2819         WLOGFD("Remote died, id: %{public}d", iter->second);
2820         auto session = GetSceneSession(iter->second);
2821         if (session == nullptr) {
2822             WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2823             return;
2824         }
2825         DestroyAndDisconnectSpecificSessionInner(iter->second);
2826     };
2827     taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2828 }
2829 
CreateAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,int32_t & persistentId,sptr<ISession> & session,SystemSessionConfig & systemConfig,sptr<IRemoteObject> token)2830 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2831     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2832     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2833     SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2834 {
2835     if (property == nullptr) {
2836         WLOGFE("property is nullptr");
2837         return WSError::WS_ERROR_NULLPTR;
2838     }
2839 
2840     if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2841         WLOGFE("create system window or modal subwindow permission denied!");
2842         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2843     }
2844 
2845     bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2846                         property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2847     bool isSystemCalling = SessionPermission::IsSystemCalling();
2848     if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2849         auto parentSession = GetSceneSession(property->GetParentPersistentId());
2850         if (parentSession) {
2851             shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2852         }
2853     }
2854     bool isPcWindow = false;
2855     IsPcWindow(isPcWindow);
2856     if (isPcWindow && property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
2857         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't block");
2858         shouldBlock = false;
2859     }
2860     if (shouldBlock) {
2861         TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2862         return WSError::WS_ERROR_INVALID_OPERATION;
2863     }
2864 
2865     if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2866         property->GetExtensionFlag() && property->GetIsUIExtensionAbilityProcess() &&
2867         SessionPermission::IsStartedByUIExtension()) {
2868         auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2869         if (extensionParentSession == nullptr) {
2870             WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2871             return WSError::WS_ERROR_NULLPTR;
2872         }
2873         SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2874         AAFwk::UIExtensionHostInfo hostInfo;
2875         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2876         if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2877             WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2878                 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2879                 hostInfo.elementName_.GetBundleName().c_str());
2880             return WSError::WS_ERROR_INVALID_WINDOW;
2881         }
2882     }
2883 
2884     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2885     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2886         WLOGFE("The alarm window has been deprecated!");
2887         return WSError::WS_ERROR_INVALID_WINDOW;
2888     }
2889 
2890     if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2891         WLOGFE("pip window is not enable to create.");
2892         return WSError::WS_DO_NOTHING;
2893     }
2894     TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2895         property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2896 
2897     // Get pid and uid before posting task.
2898     auto pid = IPCSkeleton::GetCallingRealPid();
2899     auto uid = IPCSkeleton::GetCallingUid();
2900     auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2901                     &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2902         if (property == nullptr) {
2903             WLOGFE("[WMSSub][WMSSystem] property is nullptr");
2904             return WSError::WS_ERROR_NULLPTR;
2905         }
2906         const auto& type = property->GetWindowType();
2907         // create specific session
2908         SessionInfo info;
2909         info.windowType_ = static_cast<uint32_t>(type);
2910         info.bundleName_ = property->GetSessionInfo().bundleName_;
2911         info.abilityName_ = property->GetSessionInfo().abilityName_;
2912         info.moduleName_ = property->GetSessionInfo().moduleName_;
2913         info.screenId_ = property->GetDisplayId();
2914 
2915         ClosePipWindowIfExist(type);
2916         sptr<SceneSession> newSession = RequestSceneSession(info, property);
2917         if (newSession == nullptr) {
2918             TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2919             return WSError::WS_ERROR_NULLPTR;
2920         }
2921         property->SetSystemCalling(isSystemCalling);
2922         auto errCode = newSession->ConnectInner(
2923             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2924         newSession->SetIsSystemSpecificSession(isSystemCalling);
2925         systemConfig = systemConfig_;
2926         if (property) {
2927             persistentId = property->GetPersistentId();
2928         }
2929 
2930         NotifyCreateSpecificSession(newSession, property, type);
2931         session = newSession;
2932         AddClientDeathRecipient(sessionStage, newSession);
2933         TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2934             "parentId: %{public}d, type: %{public}d",
2935             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2936         return errCode;
2937     };
2938 
2939     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2940 }
2941 
ClosePipWindowIfExist(WindowType type)2942 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2943 {
2944     if (type != WindowType::WINDOW_TYPE_PIP) {
2945         return;
2946     }
2947     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2948     for (const auto& iter: sceneSessionMap_) {
2949         auto& session = iter.second;
2950         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2951             session->NotifyCloseExistPipWindow();
2952             break;
2953         }
2954     }
2955 }
2956 
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)2957 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2958 {
2959     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2960     for (const auto& iter: sceneSessionMap_) {
2961         auto& session = iter.second;
2962         if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2963             pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2964             session->IsSessionForeground()) {
2965             if (startPiPFailedFunc_) {
2966                 startPiPFailedFunc_();
2967             }
2968             TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2969             return false;
2970         }
2971     }
2972     return true;
2973 }
2974 
isEnablePiPCreate(const sptr<WindowSessionProperty> & property)2975 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2976 {
2977     if (isScreenLocked_) {
2978         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2979         return false;
2980     }
2981     Rect pipRect = property->GetRequestRect();
2982     if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2983         TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2984         return false;
2985     }
2986     if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2987         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2988         return false;
2989     }
2990     auto parentSession = GetSceneSession(property->GetParentPersistentId());
2991     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2992         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2993         return false;
2994     }
2995     return true;
2996 }
2997 
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)2998 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2999 {
3000     WindowType type = property->GetWindowType();
3001     if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
3002         return true;
3003     }
3004 
3005     if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
3006         TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
3007         return false;
3008     }
3009 
3010     if (!SessionPermission::IsSystemCalling()) {
3011         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
3012         return false;
3013     }
3014 
3015     return true;
3016 }
3017 
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)3018 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
3019 {
3020     WindowType type = property->GetWindowType();
3021     if (WindowHelper::IsUIExtensionWindow(type)) {
3022         // UIExtension window disallowed.
3023         return false;
3024     }
3025     if (!WindowHelper::IsSystemWindow(type)) {
3026         // type is not system
3027         return true;
3028     }
3029     if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)
3030         && SessionPermission::IsStartedByInputMethod()) {
3031         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
3032         WLOGFD("check create permission success, input method app create input method window.");
3033         return true;
3034     }
3035     if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
3036         // some system types could be created by normal app
3037         return true;
3038     }
3039     if (type == WindowType::WINDOW_TYPE_FLOAT &&
3040         SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
3041         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
3042         if (systemConfig_.supportTypeFloatWindow_) {
3043             WLOGFD("check create float window permission success on 2in1 device.");
3044             return true;
3045         }
3046     }
3047     if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
3048         int32_t parentId = property->GetParentPersistentId();
3049         auto parentSession = GetSceneSession(parentId);
3050         if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
3051             SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
3052             TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
3053             return true;
3054         } else {
3055             TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
3056         }
3057     }
3058     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
3059         TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
3060         return true;
3061     }
3062     WLOGFE("check system window permission failed.");
3063     return false;
3064 }
3065 
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)3066 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
3067 {
3068     SessionInfo sessionInfo;
3069     if (property == nullptr) {
3070         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3071         return sessionInfo;
3072     }
3073     sessionInfo = property->GetSessionInfo();
3074     sessionInfo.persistentId_ = property->GetPersistentId();
3075     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
3076     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
3077     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
3078     sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
3079                                     ? SessionState::STATE_ACTIVE
3080                                     : SessionState::STATE_BACKGROUND;
3081     sessionInfo.isPersistentRecover_ = true;
3082     TLOGI(WmsLogTag::WMS_RECOVER,
3083         "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
3084         "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
3085         "windowState=%{public}u",
3086         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
3087         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_);
3088     return sessionInfo;
3089 }
3090 
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)3091 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
3092 {
3093     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
3094            "%{public}d", alivePersistentIds.size(), currentUserId_.load());
3095     alivePersistentIds_ = alivePersistentIds;
3096 }
3097 
IsNeedRecover(const int32_t persistentId)3098 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
3099 {
3100     auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
3101     if (it == alivePersistentIds_.end()) {
3102         TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
3103         return false;
3104     }
3105     return true;
3106 }
3107 
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)3108 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
3109     bool isSpecificSession)
3110 {
3111     if (property == nullptr) {
3112         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
3113         return WSError::WS_ERROR_NULLPTR;
3114     }
3115     if (!CheckSystemWindowPermission(property)) {
3116         TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
3117         return WSError::WS_ERROR_NOT_SYSTEM_APP;
3118     }
3119     if (isSpecificSession) {
3120         if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
3121             return WSError::WS_ERROR_INVALID_PARAM;
3122         }
3123     } else {
3124         if (!IsNeedRecover(property->GetPersistentId())) {
3125             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
3126             return WSError::WS_ERROR_INVALID_PARAM;
3127         }
3128     }
3129     return WSError::WS_OK;
3130 }
3131 
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)3132 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
3133     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3134     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
3135 {
3136     auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
3137     if (propCheckRet != WSError::WS_OK) {
3138         return propCheckRet;
3139     }
3140     auto pid = IPCSkeleton::GetCallingRealPid();
3141     auto uid = IPCSkeleton::GetCallingUid();
3142     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
3143         if (recoveringFinished_) {
3144             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3145             return WSError::WS_ERROR_INVALID_OPERATION;
3146         }
3147         // recover specific session
3148         SessionInfo info = RecoverSessionInfo(property);
3149         TLOGI(WmsLogTag::WMS_RECOVER, "callingWindowId = %{public}" PRIu32, property->GetCallingSessionId());
3150         ClosePipWindowIfExist(property->GetWindowType());
3151         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
3152         if (sceneSession == nullptr) {
3153             TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
3154             return WSError::WS_ERROR_NULLPTR;
3155         }
3156 
3157         auto persistentId = sceneSession->GetPersistentId();
3158         if (persistentId != info.persistentId_) {
3159             TLOGE(WmsLogTag::WMS_RECOVER,
3160                 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
3161                 info.persistentId_, persistentId, property->GetParentPersistentId());
3162             failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
3163             EraseSceneSessionMapById(persistentId);
3164             return WSError::WS_ERROR_INVALID_SESSION;
3165         }
3166 
3167         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3168         if (errCode != WSError::WS_OK) {
3169             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
3170             EraseSceneSessionMapById(persistentId);
3171             return errCode;
3172         }
3173         NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
3174         CacheSubSessionForRecovering(sceneSession, property);
3175         NotifySessionUnfocusedToClient(persistentId);
3176         AddClientDeathRecipient(sessionStage, sceneSession);
3177         session = sceneSession;
3178         return errCode;
3179     };
3180     return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
3181 }
3182 
NotifyRecoveringFinished()3183 void SceneSessionManager::NotifyRecoveringFinished()
3184 {
3185     taskScheduler_->PostAsyncTask([this]() {
3186             TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
3187             recoveringFinished_ = true;
3188             recoverSubSessionCacheMap_.clear();
3189         }, "NotifyRecoveringFinished");
3190 }
3191 
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)3192 void SceneSessionManager::CacheSubSessionForRecovering(
3193     sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
3194 {
3195     if (recoveringFinished_) {
3196         TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
3197         return;
3198     }
3199 
3200     if (sceneSession == nullptr || property == nullptr) {
3201         TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
3202         return;
3203     }
3204 
3205     auto windowType = property->GetWindowType();
3206     if (!SessionHelper::IsSubWindow(windowType)) {
3207         return;
3208     }
3209 
3210     auto persistentId = property->GetParentPersistentId();
3211     if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
3212         return;
3213     }
3214 
3215     TLOGI(WmsLogTag::WMS_RECOVER,
3216         "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
3217         sceneSession->GetPersistentId(), persistentId);
3218 
3219     if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
3220         recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
3221     } else {
3222         recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
3223     }
3224 }
3225 
RecoverCachedSubSession(int32_t persistentId)3226 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
3227 {
3228     auto iter = recoverSubSessionCacheMap_.find(persistentId);
3229     if (iter == recoverSubSessionCacheMap_.end()) {
3230         return;
3231     }
3232 
3233     TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3234     for (auto& sceneSession : iter->second) {
3235         NotifyCreateSubSession(persistentId, sceneSession);
3236     }
3237     recoverSubSessionCacheMap_.erase(iter);
3238 }
3239 
NotifySessionUnfocusedToClient(int32_t persistentId)3240 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
3241 {
3242     if (listenerController_ != nullptr) {
3243         TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3244         listenerController_->NotifySessionUnfocused(persistentId);
3245     }
3246 }
3247 
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)3248 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
3249     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3250     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
3251 {
3252     auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
3253     if (propCheckRet != WSError::WS_OK) {
3254         return propCheckRet;
3255     }
3256     auto pid = IPCSkeleton::GetCallingRealPid();
3257     auto uid = IPCSkeleton::GetCallingUid();
3258     auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
3259         if (recoveringFinished_) {
3260             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3261             return WSError::WS_ERROR_INVALID_OPERATION;
3262         }
3263         if (recoverSceneSessionFunc_ == nullptr) {
3264             TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
3265             return WSError::WS_ERROR_NULLPTR;
3266         }
3267         SessionInfo sessionInfo = RecoverSessionInfo(property);
3268         sptr<SceneSession> sceneSession = nullptr;
3269         if (SessionHelper::IsMainWindow(property->GetWindowType())) {
3270             sceneSession = RequestSceneSession(sessionInfo, nullptr);
3271         } else {
3272             sceneSession = RequestSceneSession(sessionInfo, property);
3273         }
3274         if (sceneSession == nullptr) {
3275             TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
3276             return WSError::WS_ERROR_NULLPTR;
3277         }
3278         int32_t persistentId = sceneSession->GetPersistentId();
3279         if (persistentId != sessionInfo.persistentId_) {
3280             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
3281                 sessionInfo.persistentId_, persistentId);
3282             EraseSceneSessionMapById(persistentId);
3283             return WSError::WS_ERROR_INVALID_SESSION;
3284         }
3285         auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3286         if (ret != WSError::WS_OK) {
3287             TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
3288             EraseSceneSessionMapById(sessionInfo.persistentId_);
3289             return ret;
3290         }
3291         sceneSession->SetRecovered(true);
3292         recoverSceneSessionFunc_(sceneSession, sessionInfo);
3293         NotifySessionUnfocusedToClient(persistentId);
3294         session = sceneSession;
3295         return WSError::WS_OK;
3296     };
3297     return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
3298 }
3299 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)3300 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
3301 {
3302     TLOGI(WmsLogTag::WMS_RECOVER, "called");
3303     recoverSceneSessionFunc_ = func;
3304 }
3305 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)3306 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
3307 {
3308     createSystemSessionFunc_ = func;
3309 }
3310 
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)3311 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
3312 {
3313     createKeyboardSessionFunc_ = func;
3314 }
3315 
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)3316 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
3317 {
3318     startPiPFailedFunc_ = std::move(func);
3319 }
3320 
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)3321 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
3322     const NotifyCreateSubSessionFunc& func)
3323 {
3324     TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
3325     auto task = [this, persistentId, func]() {
3326         createSubSessionFuncMap_[persistentId] = func;
3327         RecoverCachedSubSession(persistentId);
3328         return WMError::WM_OK;
3329     };
3330     taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
3331 }
3332 
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)3333 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
3334     sptr<WindowSessionProperty> property, const WindowType& type)
3335 {
3336     if (newSession == nullptr) {
3337         WLOGFE("newSession is nullptr");
3338         return;
3339     }
3340     if (property == nullptr) {
3341         WLOGFE("property is nullptr");
3342         return;
3343     }
3344     if (SessionHelper::IsSystemWindow(type)) {
3345         if (type == WindowType::WINDOW_TYPE_FLOAT) {
3346             auto parentSession = GetSceneSession(property->GetParentPersistentId());
3347             if (parentSession != nullptr) {
3348                 newSession->SetParentSession(parentSession);
3349             }
3350         }
3351         if (type == WindowType::WINDOW_TYPE_TOAST) {
3352             NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
3353         }
3354         if (type != WindowType::WINDOW_TYPE_DIALOG) {
3355             if (WindowHelper::IsSystemSubWindow(type)) {
3356                 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3357             } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
3358                 && createKeyboardSessionFunc_) {
3359                 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
3360             } else if (createSystemSessionFunc_) {
3361                 createSystemSessionFunc_(newSession);
3362             }
3363             TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
3364                 newSession->GetPersistentId(), type);
3365         } else {
3366             TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, \
3367                 type:%{public}d", newSession->GetPersistentId(), type);
3368             return;
3369         }
3370     } else if (SessionHelper::IsSubWindow(type)) {
3371         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3372         TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
3373             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
3374     } else {
3375         TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
3376             newSession->GetPersistentId(), type);
3377     }
3378 }
3379 
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)3380 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
3381 {
3382     if (session == nullptr) {
3383         TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
3384         return;
3385     }
3386     auto iter = createSubSessionFuncMap_.find(persistentId);
3387     if (iter == createSubSessionFuncMap_.end()) {
3388         TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
3389         return;
3390     }
3391 
3392     sptr<SceneSession> parentSession = nullptr;
3393     if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
3394         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3395         parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
3396     } else {
3397         parentSession = GetSceneSession(persistentId);
3398     }
3399     if (parentSession == nullptr) {
3400         TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
3401             persistentId, session->GetPersistentId());
3402         return;
3403     }
3404     parentSession->AddSubSession(session);
3405     session->SetParentSession(parentSession);
3406     if (iter->second) {
3407         iter->second(session);
3408     }
3409     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
3410         persistentId, session->GetPersistentId());
3411 }
3412 
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)3413 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
3414     const std::map<int32_t, sptr<SceneSession>>& sessionMap)
3415 {
3416     if (persistentId == INVALID_SESSION_ID) {
3417         TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
3418         return nullptr;
3419     }
3420     auto iter = sessionMap.find(persistentId);
3421     if (iter == sessionMap.end()) {
3422         WLOGFD("Error found scene session with id: %{public}d", persistentId);
3423         return nullptr;
3424     }
3425     sptr<SceneSession> parentSession = iter->second;
3426     if (parentSession == nullptr) {
3427         TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
3428         return nullptr;
3429     }
3430     bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
3431         parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
3432     if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
3433         TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
3434         return parentSession;
3435     }
3436     return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
3437 }
3438 
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)3439 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
3440 {
3441     if (session == nullptr) {
3442         TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
3443         return;
3444     }
3445 
3446     auto parentSession = GetSceneSession(persistentId);
3447     if (parentSession == nullptr) {
3448         TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
3449             persistentId, session->GetPersistentId());
3450         return;
3451     }
3452     parentSession->AddToastSession(session);
3453     session->SetParentSession(parentSession);
3454     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
3455         persistentId, session->GetPersistentId());
3456 }
3457 
UnregisterCreateSubSessionListener(int32_t persistentId)3458 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
3459 {
3460     TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
3461     auto task = [this, persistentId]() {
3462         auto iter = createSubSessionFuncMap_.find(persistentId);
3463         if (iter != createSubSessionFuncMap_.end()) {
3464             createSubSessionFuncMap_.erase(persistentId);
3465         } else {
3466             TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
3467         }
3468         return WMError::WM_OK;
3469     };
3470     taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
3471 }
3472 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)3473 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
3474 {
3475     WLOGFD("SetStatusBarEnabledChangeListener");
3476     if (!func) {
3477         WLOGFD("set func is null");
3478     }
3479     statusBarEnabledChangeFunc_ = func;
3480 }
3481 
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)3482 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
3483     const ProcessGestureNavigationEnabledChangeFunc& func)
3484 {
3485     WLOGFD("SetGestureNavigationEnabledChangeListener");
3486     if (!func) {
3487         WLOGFD("set func is null");
3488     }
3489     gestureNavigationEnabledChangeFunc_ = func;
3490 }
3491 
OnOutsideDownEvent(int32_t x,int32_t y)3492 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
3493 {
3494     TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
3495     if (outsideDownEventFunc_) {
3496         outsideDownEventFunc_(x, y);
3497     }
3498 }
3499 
NotifySessionTouchOutside(int32_t persistentId)3500 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
3501 {
3502     auto task = [this, persistentId]() {
3503         int32_t callingSessionId = INVALID_SESSION_ID;
3504         auto sceneSession = GetSceneSession(persistentId);
3505         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3506             callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
3507             TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
3508                 persistentId, callingSessionId);
3509         }
3510         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3511         for (const auto &item : sceneSessionMap_) {
3512             sceneSession = item.second;
3513             if (sceneSession == nullptr) {
3514                 continue;
3515             }
3516             if (!(sceneSession->IsVisible() ||
3517                 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3518                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
3519                 continue;
3520             }
3521             auto sessionId = sceneSession->GetPersistentId();
3522             if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
3523                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3524                 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3525                 continue;
3526             }
3527             if (sessionId == callingSessionId || sessionId == persistentId) {
3528                 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3529                 continue;
3530             }
3531             sceneSession->NotifyTouchOutside();
3532         }
3533     };
3534 
3535     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3536     return;
3537 }
3538 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)3539 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3540 {
3541     WLOGFD("SetOutsideDownEventListener");
3542     outsideDownEventFunc_ = func;
3543 }
3544 
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)3545 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
3546 {
3547     for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
3548         if (iter->second != persistentId) {
3549             continue;
3550         }
3551         if (windowDeath_ == nullptr) {
3552             TLOGE(WmsLogTag::WMS_LIFE, "death recipient is null");
3553         } else {
3554             if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
3555                 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
3556             }
3557         }
3558         remoteObjectMap_.erase(iter);
3559         break;
3560     }
3561 }
3562 
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3563 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3564 {
3565     auto sceneSession = GetSceneSession(persistentId);
3566     if (sceneSession == nullptr) {
3567         return WSError::WS_ERROR_NULLPTR;
3568     }
3569     auto ret = sceneSession->UpdateActiveStatus(false);
3570     WindowDestroyNotifyVisibility(sceneSession);
3571     auto windowType = sceneSession->GetWindowType();
3572     if (windowType == WindowType::WINDOW_TYPE_DIALOG) {
3573         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3574         if (parentSession == nullptr) {
3575             TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3576         } else {
3577             parentSession->RemoveDialogToParentSession(sceneSession);
3578         }
3579     } else if (windowType == WindowType::WINDOW_TYPE_TOAST) {
3580         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3581         if (parentSession != nullptr) {
3582             TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3583             parentSession->RemoveToastSession(persistentId);
3584         } else {
3585             TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3586         }
3587     } else if (windowType == WindowType::WINDOW_TYPE_FLOAT) {
3588         DestroySubSession(sceneSession);
3589     }
3590     ret = sceneSession->Disconnect();
3591     sceneSession->ClearSpecificSessionCbMap();
3592     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3593         DestroySubSession(sceneSession);
3594         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3595         if (parentSession != nullptr) {
3596             TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3597             parentSession->RemoveSubSession(sceneSession->GetPersistentId());
3598         } else {
3599             TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3600         }
3601         DestroyUIServiceExtensionSubWindow(sceneSession);
3602     }
3603     {
3604         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3605         EraseSceneSessionAndMarkDirtyLocked(persistentId);
3606         systemTopSceneSessionMap_.erase(persistentId);
3607         nonSystemFloatSceneSessionMap_.erase(persistentId);
3608         UnregisterCreateSubSessionListener(persistentId);
3609     }
3610     ClearSpecificSessionRemoteObjectMap(persistentId);
3611     TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3612     return ret;
3613 }
3614 
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)3615 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
3616 {
3617     if (!sceneSession) {
3618         TLOGE(WmsLogTag::WMS_SUB,"sceneSession is null");
3619         return;
3620     }
3621     auto sessionProperty = sceneSession->GetSessionProperty();
3622     if (sessionProperty && sessionProperty->GetExtensionFlag() == true &&
3623         !sessionProperty->GetIsUIExtensionAbilityProcess()) {
3624         sceneSession->NotifyDestroy();
3625         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
3626             TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
3627         TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
3628             sceneSession->GetPersistentId(), errCode);
3629     }
3630 }
3631 
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3632 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3633 {
3634     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3635     auto task = [this, persistentId, callingPid]() {
3636         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3637         auto sceneSession = GetSceneSession(persistentId);
3638         if (sceneSession == nullptr) {
3639             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3640             return WSError::WS_ERROR_NULLPTR;
3641         }
3642 
3643         if (callingPid != sceneSession->GetCallingPid()) {
3644             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3645             return WSError::WS_ERROR_INVALID_PERMISSION;
3646         }
3647         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3648     };
3649 
3650     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3651 }
3652 
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)3653 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3654     const sptr<IRemoteObject>& callback)
3655 {
3656     if (callback == nullptr) {
3657         return WSError::WS_ERROR_NULLPTR;
3658     }
3659     const auto callingPid = IPCSkeleton::GetCallingRealPid();
3660     auto task = [this, persistentId, callingPid, callback]() {
3661         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3662         auto sceneSession = GetSceneSession(persistentId);
3663         if (sceneSession == nullptr) {
3664             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3665             return WSError::WS_ERROR_NULLPTR;
3666         }
3667 
3668         if (callingPid != sceneSession->GetCallingPid()) {
3669             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3670             return WSError::WS_ERROR_INVALID_PERMISSION;
3671         }
3672         sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3673         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3674     };
3675 
3676     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3677 }
3678 
GetWindowSceneConfig() const3679 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3680 {
3681     return appWindowSceneConfig_;
3682 }
3683 
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)3684 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3685 {
3686     auto task = [this, config]() {
3687         TLOGI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3688         rotateAnimationConfig_.duration_ = config.duration_;
3689     };
3690     taskScheduler_->PostAsyncTask(task, "UpdateRotateAnimationConfig");
3691 }
3692 
ProcessBackEvent()3693 WSError SceneSessionManager::ProcessBackEvent()
3694 {
3695     auto task = [this]() {
3696         auto session = GetSceneSession(focusedSessionId_);
3697         if (!session) {
3698             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId_);
3699             return WSError::WS_ERROR_INVALID_SESSION;
3700         }
3701         TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
3702             focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3703         if (needBlockNotifyFocusStatusUntilForeground_ || !session->IsSessionValid()) {
3704             TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
3705             if (session->GetSessionInfo().abilityInfo != nullptr &&
3706                 session->GetSessionInfo().abilityInfo->unclearableMission) {
3707                 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3708                 return WSError::WS_OK;
3709             }
3710             session->RequestSessionBack(true);
3711             return WSError::WS_OK;
3712         }
3713         if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3714             rootSceneProcessBackEventFunc_();
3715         } else {
3716             session->ProcessBackEvent();
3717         }
3718         return WSError::WS_OK;
3719     };
3720 
3721     taskScheduler_->PostAsyncTask(task, __func__);
3722     return WSError::WS_OK;
3723 }
3724 
InitUserInfo(int32_t userId,std::string & fileDir)3725 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3726 {
3727     if (userId == DEFAULT_USERID || fileDir.empty()) {
3728         TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3729         return WSError::WS_DO_NOTHING;
3730     }
3731     TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3732     auto task = [this, userId, &fileDir]() {
3733         if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3734             TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3735         }
3736         if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3737             TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3738         }
3739         currentUserId_ = userId;
3740         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3741         AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3742         RegisterSecSurfaceInfoListener();
3743         RegisterConstrainedModalUIExtInfoListener();
3744         return WSError::WS_OK;
3745     };
3746     return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3747 }
3748 
NotifySwitchingUser(const bool isUserActive)3749 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3750 {
3751     auto task = [this, isUserActive]() {
3752         TLOGI(WmsLogTag::WMS_MULTI_USER, "Notify switching user. IsUserActive=%{public}u, currentUserId=%{public}d",
3753             isUserActive, currentUserId_.load());
3754         isUserBackground_ = !isUserActive;
3755         SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3756         if (isUserActive) { // switch to current user
3757             SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3758             AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3759             // notify screenSessionManager to recover current user
3760             ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3761             FlushWindowInfoToMMI(true);
3762             NotifyAllAccessibilityInfo();
3763             rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3764             UpdatePrivateStateAndNotifyForAllScreens();
3765         } else { // switch to another user
3766             SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3767             rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3768         }
3769         return WSError::WS_OK;
3770     };
3771     taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3772 }
3773 
GetBundleManager()3774 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3775 {
3776     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3777     if (systemAbilityMgr == nullptr) {
3778         WLOGFE("Failed to get SystemAbilityManager.");
3779         return nullptr;
3780     }
3781 
3782     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3783     if (bmsObj == nullptr) {
3784         WLOGFE("Failed to get BundleManagerService.");
3785         return nullptr;
3786     }
3787 
3788     return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3789 }
3790 
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)3791 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3792     const AppExecFwk::AbilityInfo& abilityInfo)
3793 {
3794     auto context = rootSceneContextWeak_.lock();
3795     if (!context) {
3796         WLOGFE("context is nullptr.");
3797         return nullptr;
3798     }
3799     auto resourceMgr = context->GetResourceManager();
3800     if (!resourceMgr) {
3801         WLOGFE("resourceMgr is nullptr.");
3802         return nullptr;
3803     }
3804     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3805     if (!resConfig) {
3806         WLOGFE("resConfig is nullptr.");
3807         return nullptr;
3808     }
3809     resourceMgr->GetResConfig(*resConfig);
3810     resourceMgr = Global::Resource::CreateResourceManager(
3811         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3812     if (!resourceMgr) {
3813         WLOGFE("resourceMgr is nullptr.");
3814         return nullptr;
3815     }
3816     resourceMgr->UpdateResConfig(*resConfig);
3817 
3818     std::string loadPath;
3819     if (!abilityInfo.hapPath.empty()) { // zipped hap
3820         loadPath = abilityInfo.hapPath;
3821     } else {
3822         loadPath = abilityInfo.resourcePath;
3823     }
3824 
3825     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3826         WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3827     }
3828     return resourceMgr;
3829 }
3830 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)3831 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3832     std::string& path, uint32_t& bgColor)
3833 {
3834     auto resourceMgr = GetResourceManager(abilityInfo);
3835     if (!resourceMgr) {
3836         WLOGFE("resourceMgr is nullptr.");
3837         return false;
3838     }
3839 
3840     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3841         WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3842         return false;
3843     }
3844 
3845     if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3846         WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3847         return false;
3848     }
3849 
3850     if (!abilityInfo.hapPath.empty()) { // zipped hap
3851         auto pos = path.find_last_of('.');
3852         if (pos == std::string::npos) {
3853             WLOGFE("Format error, path %{private}s.", path.c_str());
3854             return false;
3855         }
3856         path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3857     }
3858     return true;
3859 }
3860 
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3861 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3862 {
3863     if (!bundleMgr_) {
3864         WLOGFE("bundleMgr_ is nullptr.");
3865         return;
3866     }
3867     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3868     if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3869         WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3870         return;
3871     }
3872     AAFwk::Want want;
3873     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3874     AppExecFwk::AbilityInfo abilityInfo;
3875     if (!bundleMgr_->QueryAbilityInfo(
3876         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3877         WLOGFE("Get ability info from BMS failed!");
3878         return;
3879     }
3880 
3881     if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3882         CacheStartingWindowInfo(abilityInfo, path, bgColor);
3883     }
3884     WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3885         abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3886 }
3887 
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3888 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3889     const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3890 {
3891     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3892     std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3893     auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3894     if (iter == startingWindowMap_.end()) {
3895         return false;
3896     }
3897     auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3898     const auto& infoMap = iter->second;
3899     auto infoMapIter = infoMap.find(key);
3900     if (infoMapIter == infoMap.end()) {
3901         return false;
3902     }
3903     path = infoMapIter->second.startingWindowIconPath_;
3904     bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3905     return true;
3906 }
3907 
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)3908 void SceneSessionManager::CacheStartingWindowInfo(
3909     const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3910 {
3911     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3912     auto key = abilityInfo.moduleName + abilityInfo.name;
3913     StartingWindowInfo info = {
3914         .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3915         .startingWindowIconId_ = abilityInfo.startWindowIconId,
3916         .startingWindowBackgroundColor_ = bgColor,
3917         .startingWindowIconPath_ = path,
3918     };
3919     std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3920     auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3921     if (iter != startingWindowMap_.end()) {
3922         auto& infoMap = iter->second;
3923         infoMap.emplace(key, info);
3924         return;
3925     }
3926     if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3927         startingWindowMap_.erase(startingWindowMap_.begin());
3928     }
3929     std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3930     startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3931 }
3932 
OnBundleUpdated(const std::string & bundleName,int userId)3933 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3934 {
3935     taskScheduler_->PostAsyncTask([this, bundleName]() {
3936         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3937         auto iter = startingWindowMap_.find(bundleName);
3938         if (iter != startingWindowMap_.end()) {
3939             startingWindowMap_.erase(iter);
3940         }
3941     },
3942         "OnBundleUpdated");
3943 }
3944 
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3945 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3946 {
3947     taskScheduler_->PostAsyncTask([this]() {
3948         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3949         startingWindowMap_.clear();
3950     },
3951         "OnConfigurationUpdated");
3952 }
3953 
FillSessionInfo(sptr<SceneSession> & sceneSession)3954 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3955 {
3956     auto sessionInfo = sceneSession->GetSessionInfo();
3957     if (sessionInfo.bundleName_.empty()) {
3958         WLOGFE("bundleName_ is empty");
3959         return;
3960     }
3961     if (sessionInfo.isSystem_) {
3962         WLOGFD("is system scene!");
3963         return;
3964     }
3965     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3966         sessionInfo.moduleName_);
3967     if (abilityInfo == nullptr) {
3968         WLOGFE("abilityInfo is nullptr!");
3969         return;
3970     }
3971     sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
3972     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3973     sceneSession->SetSessionInfoTime(GetCurrentTime());
3974     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3975         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3976     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3977         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3978     }
3979     TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3980         "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3981         abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3982         abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3983 }
3984 
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)3985 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3986     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3987 {
3988     if (!bundleMgr_) {
3989         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3990         return nullptr;
3991     }
3992     AAFwk::Want want;
3993     want.SetElementName("", bundleName, abilityName, moduleName);
3994     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3995     if (abilityInfo == nullptr) {
3996         WLOGFE("abilityInfo is nullptr!");
3997         return nullptr;
3998     }
3999     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
4000         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
4001         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
4002     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
4003     if (!ret) {
4004         WLOGFE("Get ability info from BMS failed!");
4005         return nullptr;
4006     }
4007     return abilityInfo;
4008 }
4009 
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)4010 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
4011     uint32_t& topWinId, uint32_t& zOrder)
4012 {
4013     const auto& subVec = session->GetSubSession();
4014     for (const auto& subSession : subVec) {
4015         if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
4016             TLOGW(WmsLogTag::WMS_SUB,
4017                 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
4018             continue;
4019         }
4020         if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4021              subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
4022             subSession->GetZOrder() > zOrder) {
4023             topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
4024             zOrder = subSession->GetZOrder();
4025             TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
4026                 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
4027         }
4028         if (subSession->GetSubSession().size() > 0) {
4029             GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
4030         }
4031     }
4032 }
4033 
4034 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)4035 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
4036 {
4037     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
4038     auto task = [this, mainWinId, &topWinId, callingPid]() {
4039         const auto& mainSession = GetSceneSession(mainWinId);
4040         if (mainSession == nullptr) {
4041             return WMError::WM_ERROR_INVALID_WINDOW;
4042         }
4043 
4044         if (callingPid != mainSession->GetCallingPid()) {
4045             WLOGFE("Permission denied, not destroy by the same process");
4046             return WMError::WM_ERROR_INVALID_PERMISSION;
4047         }
4048         uint32_t zOrder = mainSession->GetZOrder();
4049         topWinId = mainWinId;
4050         GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
4051         TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
4052             "zOrder: %{public}d", mainWinId, topWinId, zOrder);
4053         return WMError::WM_OK;
4054     };
4055 
4056     if (!Session::IsScbCoreEnabled()) {
4057         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4058     }
4059     bool postNow = false;
4060     auto mainSession = GetSceneSession(mainWinId);
4061     if (mainSession != nullptr) {
4062         postNow = !(mainSession->GetUIStateDirty());
4063     }
4064     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
4065     if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
4066         taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
4067         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4068     }
4069     TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
4070     {
4071         std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
4072         if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
4073             std::cv_status::timeout) {
4074             TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
4075         }
4076     }
4077     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
4078 }
4079 
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)4080 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
4081     int32_t windowId, int32_t& mainWindowId)
4082 {
4083     auto iter = sceneSessionMap.find(windowId);
4084     if (iter == sceneSessionMap.end()) {
4085         TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
4086         return WMError::WM_ERROR_NULLPTR;
4087     }
4088     sptr<SceneSession> sceneSession = iter->second;
4089     if (sceneSession == nullptr) {
4090         TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
4091         return WMError::WM_ERROR_NULLPTR;
4092     }
4093     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
4094         mainWindowId = sceneSession->GetPersistentId();
4095         return WMError::WM_OK;
4096     }
4097     if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4098         WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
4099         return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
4100     }
4101     // not sub window, dialog, return invalid id
4102     mainWindowId = INVALID_SESSION_ID;
4103     return WMError::WM_OK;
4104 }
4105 
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)4106 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
4107 {
4108     if (windowId == INVALID_SESSION_ID) {
4109         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
4110         return WMError::WM_ERROR_INVALID_PARAM;
4111     }
4112     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4113     return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
4114 }
4115 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4116 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
4117     const sptr<SceneSession>& sceneSession)
4118 {
4119     auto systemBarProperties = property->GetSystemBarProperty();
4120     for (auto iter : systemBarProperties) {
4121         if (iter.first == type) {
4122             sceneSession->SetSystemBarProperty(iter.first, iter.second);
4123             TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
4124                 static_cast<int32_t>(iter.first), iter.second.enable_);
4125         }
4126     }
4127     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
4128 }
4129 
4130 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4131 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
4132     const sptr<SceneSession>& sceneSession)
4133 {
4134     if (!SessionPermission::IsSystemCalling()) {
4135         TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
4136         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4137     }
4138 
4139     sceneSession->SetTopmost(property->IsTopmost());
4140     return WMError::WM_OK;
4141 }
4142 
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)4143 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
4144     const sptr<SceneSession>& sceneSession)
4145 {
4146     bool isPcWindow = false;
4147     IsPcWindow(isPcWindow);
4148     if (isPcWindow) {
4149         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
4150         return;
4151     }
4152     auto propertyOld = sceneSession->GetSessionProperty();
4153     if (propertyOld == nullptr) {
4154         TLOGI(WmsLogTag::DEFAULT, "session property null");
4155         return;
4156     }
4157 
4158     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
4159     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
4160     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
4161         TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
4162         return;
4163     }
4164 
4165     if (IsSessionVisibleForeground(sceneSession)) {
4166         if (hideNonSystemFloatingWindowsOld) {
4167             UpdateForceHideState(sceneSession, propertyOld, false);
4168         } else {
4169             UpdateForceHideState(sceneSession, property, true);
4170         }
4171     }
4172 }
4173 
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)4174 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
4175     const sptr<WindowSessionProperty>& property, bool add)
4176 {
4177     if (systemConfig_.uiType_ == UI_TYPE_PC) {
4178         TLOGI(WmsLogTag::DEFAULT, "IsPcWindow, ineffective");
4179         return;
4180     }
4181     if (property == nullptr) {
4182         WLOGFD("property is nullptr");
4183         return;
4184     }
4185     auto persistentId = sceneSession->GetPersistentId();
4186     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
4187     bool notifyAll = false;
4188     if (add) {
4189         if (property->GetHideNonSystemFloatingWindows()) {
4190             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
4191             notifyAll = !forceHideFloatOld;
4192         } else if (property->IsFloatingWindowAppType()) {
4193             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
4194             if (forceHideFloatOld) {
4195                 sceneSession->NotifyForceHideChange(true);
4196             }
4197         }
4198     } else {
4199         if (property->GetHideNonSystemFloatingWindows()) {
4200             systemTopSceneSessionMap_.erase(persistentId);
4201             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
4202         } else if (property->IsFloatingWindowAppType()) {
4203             nonSystemFloatSceneSessionMap_.erase(persistentId);
4204             if (property->GetForceHide()) {
4205                 sceneSession->NotifyForceHideChange(false);
4206             }
4207         }
4208     }
4209     if (notifyAll) {
4210         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
4211         for (const auto& item : nonSystemFloatSceneSessionMap_) {
4212             auto forceHideSceneSession = item.second;
4213             auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
4214             if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
4215                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
4216             }
4217         }
4218     }
4219 }
4220 
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)4221 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
4222 {
4223 #ifdef POWER_MANAGER_ENABLE
4224     auto task = [this, sceneSession]() {
4225         if (sceneSession == nullptr) {
4226             WLOGFE("session is invalid");
4227             return;
4228         }
4229         WLOGFD("Win: %{public}s, is turn on%{public}d",
4230             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4231         std::string identity = IPCSkeleton::ResetCallingIdentity();
4232         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
4233             WLOGI("turn screen on");
4234             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4235         }
4236         // set ipc identity to raw
4237         IPCSkeleton::SetCallingIdentity(identity);
4238     };
4239     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
4240 
4241 #else
4242     WLOGFD("Can not found the sub system of PowerMgr");
4243 #endif
4244 }
4245 
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)4246 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
4247 {
4248 #ifdef POWER_MANAGER_ENABLE
4249     wptr<SceneSession> weakSceneSession(sceneSession);
4250     auto task = [this, weakSceneSession, requireLock]() {
4251         auto scnSession = weakSceneSession.promote();
4252         if (scnSession == nullptr) {
4253             WLOGFE("session is invalid");
4254             return;
4255         }
4256         if (requireLock && scnSession->keepScreenLock_ == nullptr) {
4257             // reset ipc identity
4258             std::string identity = IPCSkeleton::ResetCallingIdentity();
4259             scnSession->keepScreenLock_ =
4260                 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
4261                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
4262             // set ipc identity to raw
4263             IPCSkeleton::SetCallingIdentity(identity);
4264         }
4265         if (scnSession->keepScreenLock_ == nullptr) {
4266             return;
4267         }
4268         auto curScreenId = scnSession->GetSessionInfo().screenId_;
4269         auto sourceMode = ScreenSourceMode::SCREEN_ALONE;
4270         if (auto screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(curScreenId)) {
4271             sourceMode = screenSession->GetSourceMode();
4272         }
4273         bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession) && sourceMode != ScreenSourceMode::SCREEN_UNIQUE;
4274         TLOGNI(WmsLogTag::WMS_ATTRIBUTE,
4275             "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d, %{public}" PRIu64 ", %{public}d]",
4276             scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
4277             scnSession->IsVisible(), requireLock, shouldLock, curScreenId, sourceMode);
4278         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
4279         ErrCode res;
4280         std::string identity = IPCSkeleton::ResetCallingIdentity();
4281         if (shouldLock) {
4282             res = scnSession->keepScreenLock_->Lock();
4283         } else {
4284             res = scnSession->keepScreenLock_->UnLock();
4285         }
4286         // set ipc identity to raw
4287         IPCSkeleton::SetCallingIdentity(identity);
4288         if (res != ERR_OK) {
4289             WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
4290                 requireLock, res);
4291         }
4292     };
4293     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
4294 #else
4295     WLOGFD("Can not found the sub system of PowerMgr");
4296 #endif
4297 }
4298 
NotifyVisibleChange(int32_t persistentId)4299 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
4300 {
4301     auto sceneSession = GetSceneSession(persistentId);
4302     if (sceneSession == nullptr) {
4303         return false;
4304     }
4305     HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
4306     ProcessWindowModeType();
4307     return true;
4308 }
4309 
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)4310 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
4311 {
4312 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
4313     if (GetDisplayBrightness() != brightness &&
4314         GetFocusedSessionId() == sceneSession->GetPersistentId()) {
4315         PostBrightnessTask(brightness);
4316     }
4317 #else
4318     WLOGFD("Can not found the sub system of DisplayPowerMgr");
4319 #endif
4320     brightnessSessionId_ = sceneSession->GetPersistentId();
4321     return WSError::WS_OK;
4322 }
4323 
PostBrightnessTask(float brightness)4324 void SceneSessionManager::PostBrightnessTask(float brightness)
4325 {
4326     bool postTaskRet = true;
4327     bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4328     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4329         if (!isPC) {
4330             auto task = [] {
4331                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4332             };
4333             postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
4334         }
4335         SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4336     } else {
4337         auto task = [brightness, isPC] {
4338             if (isPC) {
4339                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4340                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4341             } else {
4342                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4343                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4344             }
4345         };
4346         postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
4347         SetDisplayBrightness(brightness);
4348     }
4349     if (!postTaskRet) {
4350         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
4351     }
4352 }
4353 
UpdateBrightness(int32_t persistentId)4354 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
4355 {
4356     auto sceneSession = GetSceneSession(persistentId);
4357     if (sceneSession == nullptr) {
4358         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4359         return WSError::WS_ERROR_NULLPTR;
4360     }
4361     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4362             sceneSession->GetSessionInfo().isSystem_)) {
4363         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
4364         return WSError::WS_DO_NOTHING;
4365     }
4366     auto brightness = sceneSession->GetBrightness();
4367     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
4368     bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4369     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4370         if (GetDisplayBrightness() != brightness) {
4371             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
4372             if (!isPC) {
4373                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4374             }
4375             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4376         }
4377         brightnessSessionId_ = INVALID_WINDOW_ID;
4378     } else {
4379         if (GetDisplayBrightness() != brightness) {
4380             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
4381             if (isPC) {
4382                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4383                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4384             } else {
4385                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4386                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4387             }
4388             SetDisplayBrightness(brightness);
4389         }
4390         brightnessSessionId_ = sceneSession->GetPersistentId();
4391     }
4392     return WSError::WS_OK;
4393 }
4394 
GetCurrentUserId() const4395 int32_t SceneSessionManager::GetCurrentUserId() const
4396 {
4397     return currentUserId_;
4398 }
4399 
SetDisplayBrightness(float brightness)4400 void SceneSessionManager::SetDisplayBrightness(float brightness)
4401 {
4402     displayBrightness_ = brightness;
4403 }
4404 
GetDisplayBrightness() const4405 float SceneSessionManager::GetDisplayBrightness() const
4406 {
4407     return displayBrightness_;
4408 }
4409 
SetGestureNavigaionEnabled(bool enable)4410 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
4411 {
4412     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4413         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
4414         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4415     }
4416     std::string callerBundleName = SessionPermission::GetCallingBundleName();
4417     TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
4418     auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
4419         SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
4420         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
4421             WLOGFE("callback func is null");
4422             return WMError::WM_OK;
4423         }
4424         if (gestureNavigationEnabledChangeFunc_) {
4425             gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
4426         }
4427         if (statusBarEnabledChangeFunc_) {
4428             statusBarEnabledChangeFunc_(enable, bundleName);
4429         }
4430         return WMError::WM_OK;
4431     };
4432     return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
4433 }
4434 
SetFocusedSessionId(int32_t persistentId)4435 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
4436 {
4437     if (focusedSessionId_ == persistentId) {
4438         WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
4439         return WSError::WS_DO_NOTHING;
4440     }
4441     lastFocusedSessionId_ = focusedSessionId_;
4442     focusedSessionId_ = persistentId;
4443     return WSError::WS_OK;
4444 }
4445 
GetFocusedSessionId() const4446 int32_t SceneSessionManager::GetFocusedSessionId() const
4447 {
4448     return focusedSessionId_;
4449 }
4450 
GetFocusWindowInfo(FocusChangeInfo & focusInfo)4451 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
4452 {
4453     if (!SessionPermission::IsSACalling()) {
4454         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
4455         return;
4456     }
4457     auto task = [this, &focusInfo] {
4458         if (auto sceneSession = GetSceneSession(focusedSessionId_)) {
4459             TLOGND(WmsLogTag::WMS_FOCUS, "Get focus session info success");
4460             focusInfo.windowId_ = sceneSession->GetWindowId();
4461             focusInfo.displayId_ = static_cast<DisplayId>(0);
4462             focusInfo.pid_ = sceneSession->GetCallingPid();
4463             focusInfo.uid_ = sceneSession->GetCallingUid();
4464             focusInfo.windowType_ = sceneSession->GetWindowType();
4465             focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
4466             return WSError::WS_OK;
4467         }
4468         return WSError::WS_ERROR_DESTROYED_OBJECT;
4469     };
4470     taskScheduler_->PostSyncTask(task, __func__);
4471 }
4472 
IsValidDigitString(const std::string & windowIdStr)4473 static bool IsValidDigitString(const std::string& windowIdStr)
4474 {
4475     if (windowIdStr.empty()) {
4476         return false;
4477     }
4478     for (char ch : windowIdStr) {
4479         if ((ch >= '0' && ch <= '9')) {
4480             continue;
4481         }
4482         WLOGFE("invalid window id");
4483         return false;
4484     }
4485     return true;
4486 }
4487 
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)4488 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
4489 {
4490     if (sceneSession == nullptr) {
4491         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
4492         return;
4493     }
4494     const char* const where = __func__;
4495     sceneSession->SetSessionExceptionListener([this, where](
4496         const SessionInfo& info, bool needRemoveSession = false, bool startFail = false) {
4497         auto task = [this, info, where] {
4498             auto scnSession = GetSceneSession(info.persistentId_);
4499             if (scnSession == nullptr) {
4500                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
4501                 return;
4502             }
4503             if (listenerController_ == nullptr) {
4504                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s listenerController_ is nullptr", where);
4505                 return;
4506             }
4507             if (scnSession->GetSessionInfo().isSystem_) {
4508                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where,
4509                     scnSession->GetPersistentId());
4510                 return;
4511             }
4512             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
4513                 where, info.errorCode, info.persistentId_);
4514             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
4515                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
4516                 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
4517                     "or foreground timeout, id: %{public}d", info.persistentId_);
4518                 listenerController_->NotifySessionClosed(info.persistentId_);
4519             }
4520         };
4521         taskScheduler_->PostVoidSyncTask(task, "sessionException");
4522     }, false);
4523     TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
4524 }
4525 
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)4526 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
4527 {
4528     if (sceneSession == nullptr) {
4529         WLOGFE("session is nullptr");
4530         return;
4531     }
4532     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
4533         auto sceneSession = GetSceneSession(persistentId);
4534         if (sceneSession == nullptr) {
4535             WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
4536             return;
4537         }
4538         if (sceneSession->GetSessionInfo().isSystem_) {
4539             WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
4540             return;
4541         }
4542         auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
4543         if (abilityInfoPtr == nullptr) {
4544             WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
4545             return;
4546         }
4547         if (listenerController_ == nullptr) {
4548             WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
4549             return;
4550         }
4551         if (!abilityInfoPtr->excludeFromMissions) {
4552             listenerController_->NotifySessionSnapshotChanged(persistentId);
4553         }
4554     };
4555     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
4556     WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
4557 }
4558 
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)4559 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
4560 {
4561     if (sceneSession == nullptr) {
4562         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
4563         return;
4564     }
4565     AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
4566         config.duration_ = rotateAnimationConfig_.duration_;
4567     };
4568     sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
4569     TLOGD(WmsLogTag::DEFAULT, "Register acquire Rotate Animation config success, id: %{public}d",
4570         sceneSession->GetPersistentId());
4571 }
4572 
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)4573 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
4574 {
4575     if (scnSession == nullptr) {
4576         WLOGFW("NotifySessionForCallback, scnSession is nullptr");
4577         return;
4578     }
4579     if (scnSession->GetSessionInfo().isSystem_) {
4580         WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
4581         return;
4582     }
4583     WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
4584            static_cast<uint32_t>(needRemoveSession));
4585     if (scnSession->GetSessionInfo().appIndex_ != 0) {
4586         WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
4587                scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
4588         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4589         return;
4590     }
4591     if (needRemoveSession) {
4592         WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
4593         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4594         return;
4595     }
4596     if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
4597         WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
4598     } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4599                (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4600         WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4601             scnSession->GetPersistentId());
4602         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4603         return;
4604     }
4605     WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
4606     listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
4607 }
4608 
NotifyWindowInfoChangeFromSession(int32_t persistentId)4609 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4610 {
4611     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4612     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4613     if (sceneSession == nullptr) {
4614         WLOGFE("sceneSession nullptr");
4615         return;
4616     }
4617 
4618     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4619 }
4620 
IsSessionVisible(const sptr<SceneSession> & session)4621 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4622 {
4623     if (session == nullptr) {
4624         return false;
4625     }
4626     if (Session::IsScbCoreEnabled()) {
4627         return session->IsVisible();
4628     }
4629     const auto& state = session->GetSessionState();
4630     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4631         const auto& mainOrFloatSession = session->GetMainOrFloatSession();
4632         if (mainOrFloatSession == nullptr) {
4633             TLOGE(WmsLogTag::WMS_SUB, "Can not find parent for this sub window, id: %{public}d",
4634                 session->GetPersistentId());
4635             return false;
4636         }
4637         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4638             const auto mainOrFloatSessionState = mainOrFloatSession->GetSessionState();
4639             if (mainOrFloatSessionState == SessionState::STATE_INACTIVE ||
4640                 mainOrFloatSessionState == SessionState::STATE_BACKGROUND) {
4641                 TLOGD(WmsLogTag::WMS_SUB, "Parent of this sub window is at background, id: %{public}d",
4642                     session->GetPersistentId());
4643                 return false;
4644             }
4645             WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4646             return true;
4647         }
4648         WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4649         return false;
4650     }
4651 
4652     if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
4653         TLOGD(WmsLogTag::WMS_LIFE, "Window is at foreground, id: %{public}d", session->GetPersistentId());
4654         return true;
4655     }
4656     TLOGD(WmsLogTag::WMS_LIFE, "Window is at background, id: %{public}d", session->GetPersistentId());
4657     return false;
4658 }
4659 
IsSessionVisibleForeground(const sptr<SceneSession> & session)4660 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4661 {
4662     if (session == nullptr) {
4663         return false;
4664     }
4665     if (Session::IsScbCoreEnabled()) {
4666         return session->IsVisibleForeground();
4667     }
4668     return IsSessionVisible(session);
4669 }
4670 
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)4671 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4672 {
4673     if (session == nullptr) {
4674         return;
4675     }
4676     int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4677     WSRect rect = session->GetSessionRect();
4678     std::string sName;
4679     if (session->GetSessionInfo().isSystem_) {
4680         sName = session->GetSessionInfo().abilityName_;
4681     } else {
4682         sName = session->GetWindowName();
4683     }
4684     uint32_t flag = 0;
4685     uint64_t displayId = INVALID_SCREEN_ID;
4686     auto sessionProperty = session->GetSessionProperty();
4687     if (sessionProperty) {
4688         flag = sessionProperty->GetWindowFlags();
4689         displayId = sessionProperty->GetDisplayId();
4690     }
4691     uint32_t orientation = 0;
4692     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4693         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4694     // std::setw is used to set the output width and different width values are set to keep the format aligned.
4695     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4696         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4697         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4698         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4699         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4700         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4701         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4702         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4703         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4704         << "[ "
4705         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4706         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4707         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4708         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4709         << "]"
4710         << " [ "
4711         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4712         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4713         << "]"
4714         << " [ "
4715         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4716         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4717         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4718         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4719         << "]"
4720         << std::endl;
4721 }
4722 
GetAllSessionDumpInfo(std::string & dumpInfo)4723 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4724 {
4725     std::ostringstream oss;
4726     oss << "-------------------------------------ScreenGroup 0"
4727         << "-------------------------------------" << std::endl;
4728     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
4729         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]" << std::endl;
4730     std::vector<sptr<SceneSession>> allSession;
4731     std::vector<sptr<SceneSession>> backgroundSession;
4732     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4733     {
4734         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4735         sceneSessionMapCopy = sceneSessionMap_;
4736     }
4737     for (const auto& elem : sceneSessionMapCopy) {
4738         auto curSession = elem.second;
4739         if (curSession == nullptr || (!curSession->GetSessionInfo().isSystem_ && (curSession->GetSessionState() <
4740             SessionState::STATE_FOREGROUND || curSession->GetSessionState() > SessionState::STATE_BACKGROUND))) {
4741             WLOGFW("Session is nullptr or session state is invalid, id: %{public}d, state: %{public}u",
4742                 curSession->GetPersistentId(), curSession->GetSessionState());
4743             continue;
4744         }
4745         if (IsSessionVisibleForeground(curSession)) {
4746             allSession.push_back(curSession);
4747         } else {
4748             backgroundSession.push_back(curSession);
4749         }
4750     }
4751     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4752     uint32_t count = 0;
4753     for (const auto& session : allSession) {
4754         if (session == nullptr) {
4755             continue;
4756         }
4757         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4758             oss << "---------------------------------------------------------------------------------------"
4759                 << std::endl;
4760         }
4761         DumpSessionInfo(session, oss);
4762         count++;
4763     }
4764     oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4765     oss << "SingleHand: X[" << singleHandTransform_.posX << "] Y[" << singleHandTransform_.posY << "] scale["
4766         << singleHandTransform_.scaleX << "]" << std::endl;
4767     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4768     oss << "Highlighted windows: " << GetHighlightIdsStr() << std::endl;
4769     dumpInfo.append(oss.str());
4770     return WSError::WS_OK;
4771 }
4772 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)4773 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4774 {
4775     dumpRootSceneFunc_ = func;
4776 }
4777 
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)4778 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4779     const std::vector<std::string>& params, std::string& dumpInfo)
4780 {
4781     std::vector<std::string> resetParams;
4782     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4783     if (resetParams.empty()) {
4784         WLOGI("do not dump ui info");
4785         return;
4786     }
4787 
4788     if (!session->GetSessionInfo().isSystem_) {
4789         WLOGFI("Dump normal session, not system");
4790         dumpInfoFuture_.ResetLock({});
4791         session->DumpSessionElementInfo(resetParams);
4792         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4793         for (auto& info: infos) {
4794             dumpInfo.append(info).append("\n");
4795         }
4796     } else {
4797         WLOGFI("Dump system session");
4798         std::vector<std::string> infos;
4799         dumpRootSceneFunc_(resetParams, infos);
4800         for (auto& info: infos) {
4801             dumpInfo.append(info).append("\n");
4802         }
4803     }
4804 }
4805 
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)4806 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4807     const std::string& strId)
4808 {
4809     uint64_t persistentId = std::stoull(strId);
4810     auto session = GetSceneSession(persistentId);
4811     if (session == nullptr) {
4812         return WSError::WS_ERROR_INVALID_PARAM;
4813     }
4814     auto sessionProperty = session->GetSessionProperty();
4815     if (sessionProperty == nullptr) {
4816         return WSError::WS_ERROR_INVALID_PARAM;
4817     }
4818 
4819     WSRect rect = session->GetSessionRect();
4820     std::string isVisible = session->IsVisible() ? "true" : "false";
4821     std::string focusable = session->GetFocusable() ? "true" : "false";
4822     std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4823     bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4824     std::string isPrivacyMode = privacyMode ? "true" : "false";
4825     bool isFirstFrameAvailable = true;
4826     std::ostringstream oss;
4827     oss << "WindowName: " << session->GetWindowName()  << std::endl;
4828     oss << "DisplayId: " << 0 << std::endl;
4829     oss << "WinId: " << session->GetPersistentId() << std::endl;
4830     oss << "Pid: " << session->GetCallingPid() << std::endl;
4831     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4832     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4833     oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4834     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4835     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4836     oss << "IsVisible: " << isVisible << std::endl;
4837     oss << "Focusable: "  << focusable << std::endl;
4838     oss << "DecoStatus: "  << decoStatus << std::endl;
4839     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
4840     oss << "WindowRect: " << "[ "
4841         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4842         << " ]" << std::endl;
4843     oss << "scaleX: " << session->GetScaleX() << std::endl;
4844     oss << "scaleY: " << session->GetScaleY() << std::endl;
4845     oss << "Offset: " << "[ "
4846         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4847     oss << "Scale: " << "[ "
4848         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4849         << session->GetPivotX() << ", " << session->GetPivotY()
4850         << " ]" << std::endl;
4851     dumpInfo.append(oss.str());
4852 
4853     DumpSessionElementInfo(session, params, dumpInfo);
4854     return WSError::WS_OK;
4855 }
4856 
GetSCBDebugDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params)4857 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params)
4858 {
4859     std::string cmd = ScbDumpSubscriber::JoinCommands(params, params.size());
4860 
4861     // publish data
4862     bool ret = eventHandler_->PostSyncTask([this, cmd] { return g_scbSubscriber->Publish(cmd); }, "PublishSCBDumper");
4863     if (!ret) {
4864         return WSError::WS_ERROR_INVALID_OPERATION;
4865     }
4866 
4867     // get response event
4868     auto task = [this, &dumpInfo]() {
4869         dumpInfo.append(g_scbSubscriber->GetDebugDumpInfo(WAIT_TIME));
4870         return WSError::WS_OK;
4871     };
4872     eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4873 
4874     return WSError::WS_OK;
4875 }
4876 
NotifyDumpInfoResult(const std::vector<std::string> & info)4877 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4878 {
4879     dumpInfoFuture_.SetValue(info);
4880     WLOGFD("NotifyDumpInfoResult");
4881 }
4882 
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)4883 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4884 {
4885     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4886         WLOGFE("GetSessionDumpInfo permission denied!");
4887         return WSError::WS_ERROR_INVALID_PERMISSION;
4888     }
4889 
4890     if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4891         return GetAllSessionDumpInfo(dumpInfo);
4892     }
4893     if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4894         return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4895     }
4896     if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2:params num
4897         return GetSCBDebugDumpInfo(dumpInfo, params);
4898     }
4899     if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
4900         return GetTotalUITreeInfo(dumpInfo);
4901     }
4902     return WSError::WS_ERROR_INVALID_OPERATION;
4903 }
4904 
GetTotalUITreeInfo(std::string & dumpInfo)4905 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
4906 {
4907     TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4908     if (dumpUITreeFunc_) {
4909         dumpUITreeFunc_(dumpInfo);
4910     } else {
4911         TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4912     }
4913     return WSError::WS_OK;
4914 }
4915 
SetDumpUITreeFunc(const DumpUITreeFunc & func)4916 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4917 {
4918     dumpUITreeFunc_ = func;
4919 }
4920 
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)4921 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
4922 {
4923     onFlushUIParamsFunc_ = std::move(func);
4924 }
4925 
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)4926 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
4927 {
4928     isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
4929 }
4930 
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)4931 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
4932 {
4933     taskScheduler_->PostAsyncTask([this, displayId, visible] {
4934         statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
4935         TLOGNI(WmsLogTag::WMS_IMMS,
4936             "set default visibility on display: %{public}" PRIu64 " visible: %{public}d", displayId, visible);
4937     }, __func__);
4938 }
4939 
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)4940 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
4941 {
4942     return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
4943            statusBarDefaultVisibilityPerDisplay_[displayId] : true;
4944 }
4945 
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)4946 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4947 {
4948     // notify RS
4949     WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4950         " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4951         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4952         sceneSession->GetSessionInfo().bundleName_.c_str(),
4953         sceneSession->GetSessionInfo().abilityName_.c_str(),
4954         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4955     uint64_t focusNodeId = 0; // 0 means invalid
4956     if (sceneSession->GetSurfaceNode() == nullptr) {
4957         WLOGFW("focused window surfaceNode is null");
4958     } else {
4959         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4960     }
4961     FocusAppInfo appInfo = {
4962         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4963         sceneSession->GetSessionInfo().bundleName_,
4964         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4965     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4966 }
4967 
4968 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4969 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4970 {
4971     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4972     {
4973         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4974         for (auto& iter : sceneSessionMap_) {
4975             ret.push_back(iter);
4976         }
4977     }
4978     std::sort(ret.begin(), ret.end(), cmp);
4979     return ret;
4980 }
4981 
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)4982 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4983 {
4984     if (isFromTopToBottom) {
4985         TraverseSessionTreeFromTopToBottom(func);
4986     } else {
4987         TraverseSessionTreeFromBottomToTop(func);
4988     }
4989     return;
4990 }
4991 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4992 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4993 {
4994     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4995         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4996         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4997         return lhsZOrder < rhsZOrder;
4998     };
4999     auto sceneSessionVector = GetSceneSessionVector(cmp);
5000 
5001     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
5002         auto session = iter->second;
5003         if (session == nullptr) {
5004             WLOGFE("session is nullptr");
5005             continue;
5006         }
5007         if (func(session)) {
5008             return;
5009         }
5010     }
5011     return;
5012 }
5013 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)5014 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
5015 {
5016     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5017     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
5018         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
5019         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
5020         return lhsZOrder < rhsZOrder;
5021     };
5022     auto sceneSessionVector = GetSceneSessionVector(cmp);
5023     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
5024     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
5025         auto session = iter->second;
5026         if (session == nullptr) {
5027             WLOGFE("session is nullptr");
5028             continue;
5029         }
5030         if (func(session)) {
5031             return;
5032         }
5033     }
5034     return;
5035 }
5036 
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5037 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
5038     FocusChangeReason reason)
5039 {
5040     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5041     auto sceneSession = GetSceneSession(persistentId);
5042     if (sceneSession == nullptr) {
5043         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5044         return WMError::WM_ERROR_NULLPTR;
5045     }
5046     int32_t callingPid = IPCSkeleton::GetCallingPid();
5047     if (callingPid != sceneSession->GetCallingPid() &&
5048         !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
5049         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
5050         return WMError::WM_ERROR_INVALID_CALLING;
5051     }
5052     auto task = [this, persistentId, isFocused, byForeground, reason]() {
5053         if (isFocused) {
5054             RequestSessionFocus(persistentId, byForeground, reason);
5055         } else {
5056             RequestSessionUnfocus(persistentId, reason);
5057         }
5058     };
5059     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
5060     focusChangeReason_ = reason;
5061     return WMError::WM_OK;
5062 }
5063 
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)5064 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
5065     FocusChangeReason reason)
5066 {
5067     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
5068     auto task = [this, persistentId, isFocused, byForeground, reason]() {
5069         if (isFocused) {
5070             if (reason == FocusChangeReason::FOREGROUND) {
5071                 RequestSessionFocusImmediately(persistentId);
5072                 return;
5073             }
5074             if (reason == FocusChangeReason::MOVE_UP) {
5075                 auto session = GetSceneSession(persistentId);
5076                 if (session && !session->IsFocused()) {
5077                     PostProcessFocusState state = { true, true, reason };
5078                     session->SetPostProcessFocusState(state);
5079                 }
5080                 return;
5081             }
5082             // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
5083             if (reason == FocusChangeReason::CLICK) {
5084                 return;
5085             }
5086             if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
5087                 auto session = GetSceneSession(persistentId);
5088                 if (session && !session->IsFocused()) {
5089                     PostProcessFocusState state = { true, true, reason };
5090                     session->SetPostProcessFocusState(state);
5091                 }
5092             }
5093         } else {
5094             RequestSessionUnfocus(persistentId, reason);
5095         }
5096     };
5097     taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
5098     return WMError::WM_OK;
5099 }
5100 
RequestAllAppSessionUnfocus()5101 void SceneSessionManager::RequestAllAppSessionUnfocus()
5102 {
5103     auto task = [this]() {
5104         RequestAllAppSessionUnfocusInner();
5105     };
5106     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
5107     return;
5108 }
5109 
5110 /**
5111  * request focus and ignore its state
5112  * only used when app main window start before foreground
5113 */
RequestSessionFocusImmediately(int32_t persistentId)5114 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
5115 {
5116     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
5117     // base block
5118     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
5119     if (basicCheckRet != WSError::WS_OK) {
5120         return basicCheckRet;
5121     }
5122     auto sceneSession = GetSceneSession(persistentId);
5123     if (sceneSession == nullptr) {
5124         WLOGFE("[WMSComm]session is nullptr");
5125         return WSError::WS_ERROR_INVALID_SESSION;
5126     }
5127     if (!sceneSession->GetFocusable()) {
5128         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
5129         return WSError::WS_DO_NOTHING;
5130     }
5131     if (!sceneSession->IsFocusedOnShow()) {
5132         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
5133         return WSError::WS_DO_NOTHING;
5134     }
5135 
5136     // specific block
5137     FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
5138     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
5139     if (specificCheckRet != WSError::WS_OK) {
5140         return specificCheckRet;
5141     }
5142 
5143     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5144     if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
5145         needBlockNotifyFocusStatusUntilForeground_ = true;
5146     }
5147     ShiftFocus(sceneSession, false, reason);
5148     return WSError::WS_OK;
5149 }
5150 
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)5151 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
5152 {
5153     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
5154         persistentId, byForeground, reason);
5155     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
5156     if (basicCheckRet != WSError::WS_OK) {
5157         return basicCheckRet;
5158     }
5159     auto sceneSession = GetSceneSession(persistentId);
5160     if (sceneSession == nullptr) {
5161         WLOGFE("[WMSComm]session is nullptr");
5162         return WSError::WS_ERROR_INVALID_SESSION;
5163     }
5164     if (!sceneSession->GetFocusable() || !IsSessionVisibleForeground(sceneSession)) {
5165         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
5166         return WSError::WS_DO_NOTHING;
5167     }
5168     if (!sceneSession->IsFocusedOnShow()) {
5169         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
5170         return WSError::WS_DO_NOTHING;
5171     }
5172     if (!sceneSession->IsFocusableOnShow() &&
5173         (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
5174         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
5175         return WSError::WS_DO_NOTHING;
5176     }
5177 
5178     // subwindow/dialog state block
5179     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
5180         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
5181         GetSceneSession(sceneSession->GetParentPersistentId()) &&
5182         !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
5183             TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
5184                 sceneSession->GetParentPersistentId());
5185             return WSError::WS_DO_NOTHING;
5186     }
5187     // specific block
5188     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
5189     if (specificCheckRet != WSError::WS_OK) {
5190         return specificCheckRet;
5191     }
5192 
5193     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5194     needBlockNotifyFocusStatusUntilForeground_ = false;
5195     ShiftFocus(sceneSession, false, reason);
5196     return WSError::WS_OK;
5197 }
5198 
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)5199 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
5200 {
5201     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
5202     if (persistentId == INVALID_SESSION_ID) {
5203         WLOGFE("id is invalid");
5204         return WSError::WS_ERROR_INVALID_SESSION;
5205     }
5206     auto focusedSession = GetSceneSession(focusedSessionId_);
5207     if (persistentId != focusedSessionId_ &&
5208         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
5209         TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
5210         return WSError::WS_DO_NOTHING;
5211     }
5212     // if pop menu created by desktop request unfocus, back to desktop
5213     auto lastSession = GetSceneSession(lastFocusedSessionId_);
5214     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
5215         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
5216         RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
5217             TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
5218             return WSError::WS_OK;
5219     }
5220     auto nextSession = GetNextFocusableSession(persistentId);
5221     if (nextSession == nullptr) {
5222         DumpAllSessionFocusableInfo(persistentId);
5223     }
5224 
5225     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5226     needBlockNotifyFocusStatusUntilForeground_ = false;
5227 
5228     if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
5229         return WSError::WS_OK;
5230     }
5231     if (nextSession && !nextSession->IsSessionForeground() && !nextSession->GetSessionInfo().isSystem_) {
5232         needBlockNotifyFocusStatusUntilForeground_ = true;
5233     }
5234     return ShiftFocus(nextSession, true, reason);
5235 }
5236 
RequestAllAppSessionUnfocusInner()5237 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
5238 {
5239     TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
5240     auto focusedSession = GetSceneSession(focusedSessionId_);
5241     if (!focusedSession) {
5242         TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
5243         return WSError::WS_DO_NOTHING;
5244     }
5245     if (!focusedSession->IsAppSession()) {
5246         WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
5247         return WSError::WS_DO_NOTHING;
5248     }
5249     auto nextSession = GetTopFocusableNonAppSession();
5250 
5251     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5252     needBlockNotifyFocusStatusUntilForeground_ = false;
5253     return ShiftFocus(nextSession, true, FocusChangeReason::WIND);
5254 }
5255 
RequestFocusBasicCheck(int32_t persistentId)5256 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
5257 {
5258     // basic focus rule
5259     if (persistentId == INVALID_SESSION_ID) {
5260         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
5261         return WSError::WS_ERROR_INVALID_SESSION;
5262     }
5263     if (persistentId == focusedSessionId_) {
5264         TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
5265         return WSError::WS_DO_NOTHING;
5266     }
5267     return WSError::WS_OK;
5268 }
5269 
5270 /**
5271  * @note @window.focus
5272  * When high zOrder System Session unfocus, check if the last focused app window can focus.
5273  */
CheckLastFocusedAppSessionFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & nextSession)5274 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
5275     sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
5276 {
5277     if (focusedSession == nullptr || nextSession == nullptr) {
5278         return false;
5279     }
5280 
5281     TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
5282         lastFocusedAppSessionId_, nextSession->GetPersistentId());
5283 
5284     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
5285         return false;
5286     }
5287 
5288     if (!focusedSession->IsSystemSessionAboveApp()) {
5289         return false;
5290     }
5291 
5292     auto mode = nextSession->GetWindowMode();
5293     // only when next session is app, and in split or floation
5294     if (nextSession->IsAppSession() &&
5295         (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
5296          mode == WindowMode::WINDOW_MODE_FLOATING)) {
5297         if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
5298             WSError::WS_OK) {
5299             return true;
5300         }
5301         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5302     }
5303     return false;
5304 }
5305 
5306 /**
5307  * When switching focus, check if the blockingType window has been  traversed downwards.
5308  *
5309  * @return true: traversed downwards, false: not.
5310  */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession> & requestSceneSession,sptr<SceneSession> & focusedSession,bool includingAppSession)5311 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
5312     sptr<SceneSession>& focusedSession, bool includingAppSession)
5313 {
5314     uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
5315     uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
5316     TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
5317         requestSessionZOrder, focusedSessionZOrder);
5318     if  (requestSessionZOrder < focusedSessionZOrder)  {
5319         auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
5320             includingAppSession);
5321         uint32_t topNearestBlockingZOrder = 0;
5322         if  (topNearestBlockingFocusSession)  {
5323             topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
5324             TLOGD(WmsLogTag::WMS_FOCUS,  "requestSessionZOrder: %{public}d, focusedSessionZOrder:  %{public}d\
5325                 topNearestBlockingZOrder:  %{public}d",  requestSessionZOrder,  focusedSessionZOrder,
5326                 topNearestBlockingZOrder);
5327         }
5328         if  (focusedSessionZOrder >=  topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder)  {
5329             TLOGD(WmsLogTag::WMS_FOCUS,  "focus pass through, needs to be intercepted");
5330             return true;
5331         }
5332     }
5333     TLOGD(WmsLogTag::WMS_FOCUS, "not through");
5334     return false;
5335 }
5336 
CheckTopmostWindowFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & sceneSession)5337 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
5338 {
5339     bool isFocusedMainSessionTopmost =
5340         focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
5341     auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
5342     bool isFocusedSessionParentTopmost = parentSession &&
5343         parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
5344     if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
5345         (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
5346         return true;
5347     }
5348     return false;
5349 }
5350 
CheckRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5351 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5352 {
5353     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
5354          (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
5355         (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
5356          ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
5357         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
5358         return true;
5359     }
5360     return false;
5361 }
5362 
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)5363 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
5364     const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
5365 {
5366     if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
5367         focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
5368         return false;
5369     }
5370     if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
5371         return false;
5372     }
5373     return sceneSession->GetZOrder() < focusedSession->GetZOrder();
5374 }
5375 
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)5376 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
5377     FocusChangeReason reason)
5378 {
5379     TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
5380     int32_t persistentId = sceneSession->GetPersistentId();
5381     if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5382         TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5383         return WSError::WS_ERROR_INVALID_OPERATION;
5384     }
5385     // dialog get focus
5386     if (CheckRequestFocusImmdediately(sceneSession)) {
5387         return WSError::WS_DO_NOTHING;
5388     }
5389     // blocking-type session will block lower zOrder request focus
5390     auto focusedSession = GetSceneSession(focusedSessionId_);
5391     if (focusedSession) {
5392         TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d",  reason,
5393             byForeground);
5394         if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
5395             // return ok if focused session is topmost
5396             return WSError::WS_OK;
5397         }
5398         if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
5399             sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
5400             TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
5401             byForeground = false;
5402         }
5403         if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession,  focusedSession,  true))  {
5404             TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
5405             return WSError::WS_DO_NOTHING;
5406         }
5407         if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
5408             !byForeground)  {
5409             if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
5410                 && focusedSession->IsAppSession()) {
5411                 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
5412                 return WSError::WS_OK;
5413             }
5414         }
5415         bool isBlockingType = focusedSession->IsAppSession() ||
5416             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
5417         // temp check
5418         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
5419             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
5420                 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
5421                     persistentId);
5422                 return WSError::WS_DO_NOTHING;
5423         }
5424         // desktop click temp check
5425         if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
5426             TLOGW(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
5427             return WSError::WS_DO_NOTHING;
5428         }
5429     }
5430     return WSError::WS_OK;
5431 }
5432 
CheckParentSessionVisible(const sptr<SceneSession> & session)5433 bool SceneSessionManager::CheckParentSessionVisible(const sptr<SceneSession>& session)
5434 {
5435     if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
5436         session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
5437         GetSceneSession(session->GetParentPersistentId()) &&
5438         !IsSessionVisibleForeground(GetSceneSession(session->GetParentPersistentId()))) {
5439         return false;
5440     }
5441     return true;
5442 }
5443 
DumpAllSessionFocusableInfo(int32_t persistentId)5444 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
5445 {
5446     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
5447     auto func = [this](sptr<SceneSession> session) {
5448         if (session == nullptr) {
5449             return false;
5450         }
5451         bool parentVisible = CheckParentSessionVisible(session);
5452         bool sessionVisible = IsSessionVisible(session);
5453         TLOGI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
5454             "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
5455             session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
5456             session->GetFocusable(), sessionVisible, parentVisible);
5457         return false;
5458     };
5459     TraverseSessionTree(func, true);
5460 }
5461 
GetNextFocusableSession(int32_t persistentId)5462 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
5463 {
5464     TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
5465     bool previousFocusedSessionFound = false;
5466     sptr<SceneSession> ret = nullptr;
5467     auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
5468         if (session == nullptr) {
5469             return false;
5470         }
5471         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5472             TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5473             return false;
5474         }
5475         if (previousFocusedSessionFound && session->GetFocusable() &&
5476             session->IsVisible() && CheckParentSessionVisible(session)) {
5477             ret = session;
5478             return true;
5479         }
5480         if (session->GetPersistentId() == persistentId) {
5481             previousFocusedSessionFound = true;
5482         }
5483         return false;
5484     };
5485     TraverseSessionTree(func, true);
5486     return ret;
5487 }
5488 
5489 /**
5490  * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
5491  * and it is the closest;
5492  */
GetTopNearestBlockingFocusSession(uint32_t zOrder,bool includingAppSession)5493 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
5494 {
5495     sptr<SceneSession> ret = nullptr;
5496     auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
5497         if (session == nullptr) {
5498             return false;
5499         }
5500         uint32_t sessionZOrder = session->GetZOrder();
5501         if (sessionZOrder <= zOrder) { // must be above the target session
5502             return false;
5503         }
5504         if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5505             TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
5506             return false;
5507         }
5508         auto parentSession = GetSceneSession(session->GetParentPersistentId());
5509         if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
5510             parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5511             parentSession->IsTopmost()) {
5512             TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
5513             return false;
5514         }
5515         bool isPhoneOrPad = systemConfig_.uiType_ == UI_TYPE_PHONE || systemConfig_.uiType_ == UI_TYPE_PAD;
5516         bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
5517                               (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
5518                               (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
5519         if (IsSessionVisibleForeground(session) && isBlockingType)  {
5520             ret = session;
5521             return true;
5522         }
5523         return false;
5524     };
5525     TraverseSessionTree(func, false);
5526     return ret;
5527 }
5528 
GetTopFocusableNonAppSession()5529 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
5530 {
5531     TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
5532     sptr<SceneSession> ret = nullptr;
5533     auto func = [this, &ret](sptr<SceneSession> session) {
5534         if (session == nullptr) {
5535             return false;
5536         }
5537         if (session->IsAppSession()) {
5538             return true;
5539         }
5540         if (session->GetFocusable() && IsSessionVisibleForeground(session)) {
5541             ret = session;
5542         }
5543         return false;
5544     };
5545     TraverseSessionTree(func, false);
5546     return ret;
5547 }
5548 
SetShiftFocusListener(const ProcessShiftFocusFunc & func)5549 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
5550 {
5551     TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
5552     shiftFocusFunc_ = func;
5553 }
5554 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5555 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5556 {
5557     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
5558     notifySCBAfterFocusedFunc_ = func;
5559 }
5560 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5561 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5562 {
5563     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
5564     notifySCBAfterUnfocusedFunc_ = func;
5565 }
5566 
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)5567 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
5568 {
5569     WLOGFD("SetCallingSessionIdSessionListenser");
5570     callingSessionIdChangeFunc_ = func;
5571 }
5572 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)5573 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
5574 {
5575     WLOGFD("SetStartUIAbilityErrorListener");
5576     startUIAbilityErrorFunc_ = func;
5577 }
5578 
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)5579 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
5580     const AbilityManagerCollaboratorRegisteredFunc& func)
5581 {
5582     auto task = [this, func] {
5583         abilityManagerCollaboratorRegisteredFunc_ = func;
5584     };
5585     taskScheduler_->PostAsyncTask(task, __func__);
5586 }
5587 
ShiftFocus(sptr<SceneSession> & nextSession,bool isProactiveUnfocus,FocusChangeReason reason)5588 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, bool isProactiveUnfocus,
5589     FocusChangeReason reason)
5590 {
5591     // unfocus
5592     int32_t focusedId = focusedSessionId_;
5593     auto focusedSession = GetSceneSession(focusedSessionId_);
5594     UpdateFocusStatus(focusedSession, false);
5595     // focus
5596     int32_t nextId = INVALID_SESSION_ID;
5597     if (nextSession == nullptr) {
5598         std::string sessionLog(GetAllSessionFocusInfo());
5599         TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
5600             focusedSessionId_, sessionLog.c_str());
5601     } else {
5602         nextId = nextSession->GetPersistentId();
5603     }
5604     UpdateFocusStatus(nextSession, true);
5605     UpdateHighlightStatus(focusedSession, nextSession, isProactiveUnfocus);
5606     if (shiftFocusFunc_ != nullptr) {
5607         shiftFocusFunc_(nextId);
5608     }
5609     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5610     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5611     if (!scbPrevFocus && scbCurrFocus) {
5612         if (notifySCBAfterFocusedFunc_ != nullptr) {
5613             notifySCBAfterFocusedFunc_();
5614         }
5615     } else if (scbPrevFocus && !scbCurrFocus) {
5616         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5617             notifySCBAfterUnfocusedFunc_();
5618         }
5619     }
5620     TLOGI(WmsLogTag::WMS_FOCUS, "ShiftFocus, focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5621         focusedId, nextId, reason);
5622     return WSError::WS_OK;
5623 }
5624 
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5625 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5626 {
5627     if (sceneSession == nullptr) {
5628         if (isFocused) {
5629             SetFocusedSessionId(INVALID_SESSION_ID);
5630             lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5631         }
5632         return;
5633     }
5634     TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5635         sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5636     // set focused
5637     if (isFocused) {
5638         SetFocusedSessionId(sceneSession->GetPersistentId());
5639         if (sceneSession->IsAppOrLowerSystemSession()) {
5640             lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5641         }
5642     }
5643     sceneSession->UpdateFocus(isFocused);
5644     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5645         NotifyFocusStatus(sceneSession, isFocused);
5646     }
5647 }
5648 
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5649 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5650 {
5651     if (sceneSession == nullptr) {
5652         WLOGFE("[WMSComm]session is nullptr");
5653         if (isFocused) {
5654             auto prevSession = GetSceneSession(lastFocusedSessionId_);
5655             NotifyUnFocusedByMission(prevSession);
5656         }
5657         return;
5658     }
5659     int32_t persistentId = sceneSession->GetPersistentId();
5660 
5661     TLOGI(WmsLogTag::WMS_FOCUS,
5662         "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5663         sceneSession->GetSessionInfo().bundleName_.c_str(),
5664         sceneSession->GetSessionInfo().abilityName_.c_str(),
5665         sceneSession->GetWindowNameAllType().c_str(),
5666         persistentId, isFocused);
5667     if (isFocused) {
5668         if (IsSessionVisibleForeground(sceneSession)) {
5669             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5670         }
5671         UpdateBrightness(focusedSessionId_);
5672         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5673     }
5674     // notify window manager
5675     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5676         sceneSession->GetWindowId(),
5677         static_cast<DisplayId>(0),
5678         sceneSession->GetCallingPid(),
5679         sceneSession->GetCallingUid(),
5680         sceneSession->GetWindowType(),
5681         sceneSession->GetAbilityToken()
5682     );
5683     SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5684     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5685     sceneSession->NotifyFocusStatus(isFocused);
5686     // notify listenerController
5687     auto prevSession = GetSceneSession(lastFocusedSessionId_);
5688     if (isFocused && MissionChanged(prevSession, sceneSession)) {
5689         NotifyFocusStatusByMission(prevSession, sceneSession);
5690     }
5691 }
5692 
5693 /** @note @window.focus */
UpdateHighlightStatus(const sptr<SceneSession> & preSceneSession,const sptr<SceneSession> & currSceneSession,bool isProactiveUnfocus)5694 void SceneSessionManager::UpdateHighlightStatus(const sptr<SceneSession>& preSceneSession,
5695     const sptr<SceneSession>& currSceneSession, bool isProactiveUnfocus)
5696 {
5697     if (preSceneSession == nullptr || currSceneSession == nullptr) {
5698         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5699         return;
5700     }
5701     bool needBlockHighlightNotify = needBlockNotifyFocusStatusUntilForeground_;
5702     if(isProactiveUnfocus){
5703         TLOGD(WmsLogTag::WMS_FOCUS, "proactiveUnfocus");
5704         RemoveHighlightSessionIds(preSceneSession);
5705     }
5706     if(currSceneSession->GetSessionProperty()->GetExclusivelyHighlighted()) {
5707         TLOGD(WmsLogTag::WMS_FOCUS, "exclusively highlighted");
5708         SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5709         return;
5710     }
5711     if(currSceneSession->GetSessionInfo().isSystem_) {
5712         TLOGD(WmsLogTag::WMS_FOCUS, "system highlighted");
5713         AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5714         return;
5715     }
5716     if(currSceneSession->IsSameMainSession(preSceneSession)) {
5717         TLOGD(WmsLogTag::WMS_FOCUS, "related highlighted");
5718         AddHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5719         return;
5720     }
5721     TLOGD(WmsLogTag::WMS_FOCUS, "highlighted");
5722     SetHighlightSessionIds(currSceneSession, needBlockHighlightNotify);
5723 }
5724 
5725 /** @note @window.focus */
SetHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)5726 void SceneSessionManager::SetHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
5727 {
5728     if (sceneSession == nullptr) {
5729         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5730         return;
5731     }
5732     {
5733         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5734         for (auto persistentId : highlightIds_) {
5735             auto session = GetSceneSession(persistentId);
5736             if (session == nullptr) {
5737                 TLOGE(WmsLogTag::WMS_FOCUS, "session is nullptr");
5738                 continue;
5739             }
5740             if (sceneSession->GetPersistentId() != persistentId) {
5741                 session->UpdateHighlightStatus(false, false);
5742             }
5743         }
5744         sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
5745         highlightIds_.clear();
5746         highlightIds_.insert(sceneSession->GetPersistentId());
5747     }
5748     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
5749 }
5750 
5751 /** @note @window.focus */
AddHighlightSessionIds(const sptr<SceneSession> & sceneSession,bool needBlockHighlightNotify)5752 void SceneSessionManager::AddHighlightSessionIds(const sptr<SceneSession>& sceneSession, bool needBlockHighlightNotify)
5753 {
5754     if (sceneSession == nullptr) {
5755         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5756         return;
5757     }
5758     sceneSession->UpdateHighlightStatus(true, needBlockHighlightNotify);
5759     {
5760         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5761         highlightIds_.insert(sceneSession->GetPersistentId());
5762     }
5763     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
5764 }
5765 
5766 /** @note @window.focus */
RemoveHighlightSessionIds(const sptr<SceneSession> & sceneSession)5767 void SceneSessionManager::RemoveHighlightSessionIds(const sptr<SceneSession>& sceneSession)
5768 {
5769     if (sceneSession == nullptr) {
5770         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
5771         return;
5772     }
5773     {
5774         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5775         if (highlightIds_.find(sceneSession->GetPersistentId()) != highlightIds_.end()) {
5776             sceneSession->UpdateHighlightStatus(false, false);
5777             highlightIds_.erase(sceneSession->GetPersistentId());
5778         } else {
5779             TLOGE(WmsLogTag::WMS_FOCUS, "not found scene session with id: %{public}d", sceneSession->GetPersistentId());
5780         }
5781 
5782     }
5783     TLOGI(WmsLogTag::WMS_FOCUS, "highlightIds: %{public}s", GetHighlightIdsStr().c_str());
5784 }
5785 
5786 /** @note @window.focus */
GetHighlightIdsStr()5787 std::string SceneSessionManager::GetHighlightIdsStr()
5788 {
5789     std::ostringstream oss;
5790     {
5791         std::lock_guard<std::mutex> lock(highlightIdsMutex_);
5792         for (auto it = highlightIds_.begin(); it != highlightIds_.end(); it++) {
5793             oss << *it;
5794             if(std::next(it) != highlightIds_.end()) {
5795                 oss << ", ";
5796             }
5797         }
5798 
5799     }
5800     return oss.str();
5801 }
5802 
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)5803 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5804     const std::string& reason)
5805 {
5806     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5807     nlohmann::json payload;
5808     payload.emplace("uid", uid);
5809     payload.emplace("bundleName", bundleName);
5810     payload.emplace("reason", reason);
5811     nlohmann::json reply;
5812     int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5813     return ret;
5814 }
5815 
NotifyFocusStatusByMission(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5816 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5817 {
5818     if (listenerController_ != nullptr) {
5819         if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5820             TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", prevSession->GetMissionId());
5821             listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5822         }
5823         if (currSession && !currSession->GetSessionInfo().isSystem_) {
5824             TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionFocused, id: %{public}d", currSession->GetMissionId());
5825             listenerController_->NotifySessionFocused(currSession->GetMissionId());
5826         }
5827     }
5828 }
5829 
NotifyUnFocusedByMission(sptr<SceneSession> & sceneSession)5830 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5831 {
5832     if (listenerController_ == nullptr) {
5833         return;
5834     }
5835     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5836         TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", sceneSession->GetMissionId());
5837         listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5838     }
5839 }
5840 
MissionChanged(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5841 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5842 {
5843     if (prevSession == nullptr && currSession == nullptr) {
5844         return false;
5845     }
5846     if (prevSession == nullptr || currSession == nullptr) {
5847         return true;
5848     }
5849     return prevSession->GetMissionId() != currSession->GetMissionId();
5850 }
5851 
GetAllSessionFocusInfo()5852 std::string SceneSessionManager::GetAllSessionFocusInfo()
5853 {
5854     std::ostringstream os;
5855     auto func = [&os](sptr<SceneSession> session) {
5856         if (session == nullptr) {
5857             WLOGE("sceneSession is nullptr");
5858             return false;
5859         }
5860         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5861            " ,focusable: "<< session->GetFocusable() << ";";
5862         return false;
5863     };
5864     TraverseSessionTree(func, true);
5865     return os.str();
5866 }
5867 
UpdateFocus(int32_t persistentId,bool isFocused)5868 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5869 {
5870     auto task = [this, persistentId, isFocused]() {
5871         // notify session and client
5872         auto sceneSession = GetSceneSession(persistentId);
5873         if (sceneSession == nullptr) {
5874             WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5875             return WSError::WS_ERROR_INVALID_WINDOW;
5876         }
5877         WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5878             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5879         // focusId change
5880         if (isFocused) {
5881             SetFocusedSessionId(persistentId);
5882             UpdateBrightness(focusedSessionId_);
5883             FocusIDChange(persistentId, sceneSession);
5884         } else if (persistentId == GetFocusedSessionId()) {
5885             SetFocusedSessionId(INVALID_SESSION_ID);
5886         }
5887         // notify window manager
5888         sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5889             sceneSession->GetWindowId(),
5890             static_cast<DisplayId>(0),
5891             sceneSession->GetCallingPid(),
5892             sceneSession->GetCallingUid(),
5893             sceneSession->GetWindowType(),
5894             sceneSession->GetAbilityToken()
5895         );
5896         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5897         WSError res = WSError::WS_OK;
5898         res = sceneSession->UpdateFocus(isFocused);
5899         if (res != WSError::WS_OK) {
5900             return res;
5901         }
5902         WLOGFI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5903                sceneSession->GetSessionInfo().isSystem_);
5904         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
5905             if (isFocused) {
5906                 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
5907                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5908             } else {
5909                 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5910                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5911             }
5912         }
5913         return WSError::WS_OK;
5914     };
5915 
5916     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5917     return WSError::WS_OK;
5918 }
5919 
UpdateWindowMode(int32_t persistentId,int32_t windowMode)5920 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5921 {
5922     WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
5923     auto sceneSession = GetSceneSession(persistentId);
5924     if (sceneSession == nullptr) {
5925         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
5926         return WSError::WS_ERROR_INVALID_WINDOW;
5927     }
5928     WindowMode mode = static_cast<WindowMode>(windowMode);
5929     return sceneSession->UpdateWindowMode(mode);
5930 }
5931 
GetNormalSingleHandTransform() const5932 SingleHandTransform SceneSessionManager::GetNormalSingleHandTransform() const
5933 {
5934     return singleHandTransform_;
5935 }
5936 
NotifySingleHandInfoChange(float singleHandScaleX,float singleHandScaleY,SingleHandMode singleHandMode)5937 void SceneSessionManager::NotifySingleHandInfoChange(
5938     float singleHandScaleX, float singleHandScaleY, SingleHandMode singleHandMode)
5939 {
5940     const char* const funcName = __func__;
5941     taskScheduler_->PostAsyncTask([this, singleHandScaleX, singleHandScaleY, singleHandMode, funcName] {
5942         if (systemConfig_.uiType_ != UI_TYPE_PHONE) {
5943             TLOGNI(WmsLogTag::WMS_LAYOUT, "%{public}s: only support phone", funcName);
5944             return;
5945         }
5946         int32_t displayWidth = 0;
5947         int32_t displayHeight = 0;
5948         ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5949         if (!GetDisplaySizeById(defaultScreenId, displayWidth, displayHeight)) {
5950             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s: get display size failed", funcName);
5951             return;
5952         }
5953         switch (singleHandMode) {
5954             case SingleHandMode::MIDDLE:
5955                 singleHandTransform_.posX = 0;
5956                 singleHandTransform_.posY = 0;
5957                 break;
5958             case SingleHandMode::LEFT:
5959                 singleHandTransform_.posX = 0;
5960                 singleHandTransform_.posY =
5961                     static_cast<int32_t>(static_cast<float>(displayHeight) * (1 - singleHandScaleY));
5962                 break;
5963             case SingleHandMode::RIGHT:
5964                 singleHandTransform_.posX =
5965                     static_cast<int32_t>(static_cast<float>(displayWidth) * (1 - singleHandScaleX));
5966                 singleHandTransform_.posY =
5967                     static_cast<int32_t>(static_cast<float>(displayHeight) * (1 - singleHandScaleY));
5968                 break;
5969             default:
5970                 break;
5971         }
5972         singleHandTransform_.scaleX = singleHandScaleX;
5973         singleHandTransform_.scaleY = singleHandScaleY;
5974         {
5975             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5976             for (const auto& [_, sceneSession] : sceneSessionMap_) {
5977                 if (sceneSession == nullptr || sceneSession->GetSessionProperty()->GetDisplayId() != defaultScreenId ||
5978                     sceneSession->GetWindowName().find("OneHandModeBackground", 0) != std::string::npos) {
5979                     continue;
5980                 }
5981                 sceneSession->SetSingleHandTransform(singleHandTransform_);
5982                 sceneSession->NotifySingleHandTransformChange(singleHandTransform_);
5983             }
5984         }
5985         FlushWindowInfoToMMI();
5986     }, funcName);
5987 }
5988 
RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc && func)5989 void SceneSessionManager::RegisterGetRSNodeByStringIDFunc(GetRSNodeByStringIDFunc&& func)
5990 {
5991     getRSNodeByStringIDFunc_ = std::move(func);
5992 }
5993 
RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc && func)5994 void SceneSessionManager::RegisterSetTopWindowBoundaryByIDFunc(SetTopWindowBoundaryByIDFunc&& func)
5995 {
5996     setTopWindowBoundaryByIDFunc_ = std::move(func);
5997 }
5998 
RegisterSingleHandContainerNode(const std::string & stringId)5999 void SceneSessionManager::RegisterSingleHandContainerNode(const std::string& stringId)
6000 {
6001     if (getRSNodeByStringIDFunc_ == nullptr) {
6002         TLOGE(WmsLogTag::WMS_LAYOUT, "getRSNodeByStringIDFunc is nullptr");
6003         return;
6004     }
6005     auto rsNode = getRSNodeByStringIDFunc_(stringId);
6006     if (rsNode == nullptr) {
6007         TLOGE(WmsLogTag::WMS_LAYOUT, "node is nullptr");
6008         return;
6009     }
6010     TLOGI(WmsLogTag::WMS_LAYOUT, "get OneHandModeBox node, id: %{public}" PRIu64, rsNode->GetId());
6011     rsInterface_.SetWindowContainer(rsNode->GetId(), true);
6012 
6013     if (setTopWindowBoundaryByIDFunc_ == nullptr) {
6014         TLOGE(WmsLogTag::WMS_LAYOUT, "setTopWindowBoundaryByIDFunc is nullptr");
6015         return;
6016     }
6017     setTopWindowBoundaryByIDFunc_(stringId);
6018 }
6019 
6020 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)6021 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
6022     MMI::PointerEvent::PointerItem& pointerItem)
6023 {
6024     struct PointerEventData {
6025         double x;
6026         double y;
6027         uint64_t time;
6028     } pointerEventData = {
6029         .x = pointerItem.GetDisplayX(),
6030         .y = pointerItem.GetDisplayY(),
6031         .time = pointerEvent->GetActionTime()
6032     };
6033 
6034     const uint32_t MAX_HMAC_SIZE = 64;
6035     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
6036     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
6037     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
6038     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
6039         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
6040         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
6041     }
6042 }
6043 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
6044 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)6045 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
6046 {
6047     if (!pointerEvent) {
6048         WLOGFE("pointerEvent is null");
6049         return WSError::WS_ERROR_NULLPTR;
6050     }
6051     MMI::PointerEvent::PointerItem pointerItem;
6052     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
6053         WLOGFE("Failed to get pointerItem");
6054         return WSError::WS_ERROR_INVALID_PARAM;
6055     }
6056 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
6057     FillSecCompEnhanceData(pointerEvent, pointerItem);
6058 #endif
6059     TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d,action=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
6060         pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
6061     pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
6062     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
6063     return WSError::WS_OK;
6064 }
6065 
SetScreenLocked(const bool isScreenLocked)6066 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
6067 {
6068     isScreenLocked_ = isScreenLocked;
6069     DeleteStateDetectTask();
6070 }
6071 
SetUserAuthPassed(bool isUserAuthPassed)6072 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
6073 {
6074     taskScheduler_->PostTask([this, isUserAuthPassed] {
6075         isUserAuthPassed_ = isUserAuthPassed;
6076     }, __func__);
6077 }
6078 
DeleteStateDetectTask()6079 void SceneSessionManager::DeleteStateDetectTask()
6080 {
6081     if (!IsScreenLocked()) {
6082         return;
6083     }
6084     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6085     for (auto iter : sceneSessionMap_) {
6086         auto& session = iter.second;
6087         if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
6088             taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
6089             DetectTaskInfo detectTaskInfo;
6090             session->SetDetectTaskInfo(detectTaskInfo);
6091         }
6092     }
6093 }
6094 
IsScreenLocked() const6095 bool SceneSessionManager::IsScreenLocked() const
6096 {
6097     return isScreenLocked_;
6098 }
6099 
IsUserAuthPassed() const6100 bool SceneSessionManager::IsUserAuthPassed() const
6101 {
6102     return isUserAuthPassed_;
6103 }
6104 
RegisterWindowChanged(const WindowChangedFunc & func)6105 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
6106 {
6107     WindowChangedFunc_ = func;
6108 }
6109 
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)6110 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
6111     const std::unordered_set<std::string>& privacyBundles)
6112 {
6113     bool needNotify = false;
6114     static int reSendTimes = MAX_RESEND_TIMES;
6115     std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
6116     do {
6117         if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
6118             TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
6119             needNotify = !privacyBundles.empty();
6120             break;
6121         }
6122         const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
6123         if (lastPrivacyBundles.size() != privacyBundles.size()) {
6124             TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
6125                   lastPrivacyBundles.size(), privacyBundles.size());
6126             needNotify = true;
6127             break;
6128         }
6129         for (const auto& bundle : lastPrivacyBundles) {
6130             if (privacyBundles.find(bundle) == privacyBundles.end()) {
6131                 needNotify = true;
6132                 break;
6133             }
6134         }
6135     } while (false);
6136 
6137     TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
6138           displayId, needNotify);
6139     if (needNotify) {
6140         reSendTimes = MAX_RESEND_TIMES;
6141         privacyBundleMap_[displayId] = privacyBundles;
6142     } else if (reSendTimes > 0) {
6143         needNotify = true;
6144         reSendTimes--;
6145         privacyBundleMap_[displayId] = privacyBundles;
6146     }
6147     return needNotify;
6148 }
6149 
UpdatePrivateStateAndNotify(uint32_t persistentId)6150 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
6151 {
6152     auto sceneSession = GetSceneSession(persistentId);
6153     if (sceneSession == nullptr) {
6154         TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
6155         return;
6156     }
6157 
6158     auto sessionProperty = sceneSession->GetSessionProperty();
6159     if (sessionProperty == nullptr) {
6160         TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
6161         return;
6162     }
6163     auto displayId = sessionProperty->GetDisplayId();
6164     std::unordered_set<std::string> privacyBundleList;
6165     GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
6166     if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
6167         return;
6168     }
6169 
6170     std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
6171     ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
6172         !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
6173     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
6174     if (!bundleListForNotify.empty()) {
6175         TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
6176     }
6177     for (const auto& bundle : bundleListForNotify) {
6178         TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
6179               displayId, bundle.c_str());
6180     }
6181 }
6182 
UpdatePrivateStateAndNotifyForAllScreens()6183 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
6184 {
6185     auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
6186     for (auto& iter : screenProperties) {
6187         auto displayId = iter.first;
6188         std::unordered_set<std::string> privacyBundleList;
6189         GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
6190 
6191         ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
6192             !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
6193     }
6194 }
6195 
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)6196 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
6197     std::unordered_set<std::string>& privacyBundles)
6198 {
6199     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6200     for (const auto& item : sceneSessionMap_) {
6201         sptr<SceneSession> sceneSession = item.second;
6202         if (sceneSession == nullptr) {
6203             TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
6204             continue;
6205         }
6206         auto sessionProperty = sceneSession->GetSessionProperty();
6207         if (sessionProperty == nullptr) {
6208             TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
6209             continue;
6210         }
6211         auto currentDisplayId = sessionProperty->GetDisplayId();
6212         if (displayId != currentDisplayId) {
6213             continue;
6214         }
6215         bool isForeground =  sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
6216             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
6217         if (isForeground && sceneSession->GetParentSession() != nullptr) {
6218             isForeground = isForeground &&
6219                 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
6220                 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
6221         }
6222         bool isPrivate = sessionProperty->GetPrivacyMode() ||
6223             sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
6224         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
6225         if ((isForeground || IsSystemWindowVisible) && isPrivate) {
6226             if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
6227                 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
6228             } else {
6229                 TLOGD(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
6230                 privacyBundles.insert(sceneSession->GetWindowName());
6231             }
6232         }
6233     }
6234 }
6235 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)6236 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6237 {
6238     NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
6239         this->OnSessionStateChange(persistentId, state);
6240     };
6241     if (sceneSession == nullptr) {
6242         WLOGFE("session is nullptr");
6243         return;
6244     }
6245     sceneSession->SetSessionStateChangeNotifyManagerListener(func);
6246     WLOGFD("RegisterSessionStateChangeFunc success");
6247 }
6248 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)6249 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6250 {
6251     wptr<SceneSessionManager> weakSessionManager = this;
6252     NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
6253         auto sceneSessionManager = weakSessionManager.promote();
6254         if (sceneSessionManager == nullptr) {
6255             return;
6256         }
6257         sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
6258     };
6259     if (sceneSession == nullptr) {
6260         WLOGFE("session is nullptr");
6261         return;
6262     }
6263     sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
6264 }
6265 
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)6266 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6267 {
6268     NotifyRequestFocusStatusNotifyManagerFunc func =
6269     [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
6270         this->RequestFocusStatus(persistentId, isFocused, byForeground, reason);
6271     };
6272     if (sceneSession == nullptr) {
6273         WLOGFE("session is nullptr");
6274         return;
6275     }
6276     sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
6277     WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
6278 }
6279 
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)6280 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
6281 {
6282     GetStateFromManagerFunc func = [this](const ManagerState key) {
6283         switch (key)
6284         {
6285         case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
6286             return this->IsScreenLocked();
6287             break;
6288         default:
6289             return false;
6290             break;
6291         }
6292     };
6293     if (sceneSession == nullptr) {
6294         WLOGFE("session is nullptr");
6295         return;
6296     }
6297     sceneSession->SetGetStateFromManagerListener(func);
6298     WLOGFD("RegisterGetStateFromManagerFunc success");
6299 }
6300 
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)6301 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
6302 {
6303     SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
6304         const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
6305         if (sceneSession == nullptr || property == nullptr) {
6306             TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
6307             return;
6308         }
6309         switch (action) {
6310             case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
6311                 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
6312                 break;
6313             case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
6314             case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
6315             case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
6316             case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
6317             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
6318             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
6319                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6320                 break;
6321             case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
6322                 SetBrightness(sceneSession, property->GetBrightness());
6323                 break;
6324             case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
6325             case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
6326                 UpdatePrivateStateAndNotify(property->GetPersistentId());
6327                 break;
6328             case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
6329                 CheckAndNotifyWaterMarkChangedResult();
6330                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6331                 break;
6332             case WSPropertyChangeAction::ACTION_UPDATE_MODE:
6333                 if (sceneSession->GetSessionProperty() != nullptr) {
6334                     ProcessWindowModeType();
6335                 }
6336                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
6337                 break;
6338             case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
6339                 HandleHideNonSystemFloatingWindows(property, sceneSession);
6340                 break;
6341             case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
6342                 FlushWindowInfoToMMI();
6343                 break;
6344             default:
6345                 break;
6346         }
6347     };
6348     if (sceneSession != nullptr) {
6349         sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
6350     }
6351 }
6352 
OnSessionStateChange(int32_t persistentId,const SessionState & state)6353 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
6354     int32_t persistentId, const SessionState& state)
6355 {
6356     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
6357     WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
6358     auto sceneSession = GetSceneSession(persistentId);
6359     if (sceneSession == nullptr) {
6360         WLOGFD("session is nullptr");
6361         return;
6362     }
6363     switch (state) {
6364         case SessionState::STATE_FOREGROUND:
6365             ProcessFocusWhenForeground(sceneSession);
6366             if (!IsSessionVisibleForeground(sceneSession)) {
6367                 sceneSession->SetPostProcessProperty(true);
6368                 break;
6369             }
6370             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
6371             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
6372             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
6373             UpdatePrivateStateAndNotify(persistentId);
6374             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6375                 ProcessSubSessionForeground(sceneSession);
6376             }
6377             break;
6378         case SessionState::STATE_BACKGROUND:
6379             NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
6380             RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
6381             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
6382             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
6383             HandleKeepScreenOn(sceneSession, false);
6384             UpdatePrivateStateAndNotify(persistentId);
6385             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6386                 ProcessSubSessionBackground(sceneSession);
6387             }
6388             break;
6389         default:
6390             break;
6391     }
6392     ProcessWindowModeType();
6393 }
6394 
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)6395 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
6396 {
6397     auto persistentId = sceneSession->GetPersistentId();
6398     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
6399         persistentId == focusedSessionId_) {
6400         if (needBlockNotifyFocusStatusUntilForeground_) {
6401             needBlockNotifyUnfocusStatus_ = false;
6402             needBlockNotifyFocusStatusUntilForeground_ = false;
6403             NotifyFocusStatus(sceneSession, true);
6404             sceneSession->NotifyHighlightChange(true);
6405         }
6406     } else if (!sceneSession->IsFocusedOnShow()) {
6407         sceneSession->SetFocusedOnShow(true);
6408     } else {
6409         if (Session::IsScbCoreEnabled()) {
6410             ProcessFocusWhenForegroundScbCore(sceneSession);
6411         } else {
6412             RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
6413         }
6414         RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
6415     }
6416 }
6417 
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)6418 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
6419 {
6420     if (sceneSession == nullptr) {
6421         TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
6422         return;
6423     }
6424     if (sceneSession->IsFocusableOnShow()) {
6425         if (IsSessionVisibleForeground(sceneSession)) {
6426             RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
6427         } else {
6428             PostProcessFocusState state = {true, true, FocusChangeReason::APP_FOREGROUND};
6429             sceneSession->SetPostProcessFocusState(state);
6430         }
6431     } else {
6432         TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
6433             sceneSession->GetPersistentId());
6434     }
6435 }
6436 
ProcessWindowModeType()6437 void SceneSessionManager::ProcessWindowModeType()
6438 {
6439     if (isScreenLocked_) {
6440         return;
6441     }
6442     NotifyRSSWindowModeTypeUpdate();
6443 }
6444 
IsSmallFoldProduct()6445 static bool IsSmallFoldProduct()
6446 {
6447     static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
6448     if (foldScreenType.empty()) {
6449         return false;
6450     }
6451     return foldScreenType[0] == '2';
6452 }
6453 
IsInSecondaryScreen(const sptr<SceneSession> & sceneSession)6454 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
6455 {
6456     auto sessionProperty = sceneSession->GetSessionProperty();
6457     if (sessionProperty == nullptr) {
6458         TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
6459         return false;
6460     }
6461     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6462     return sessionProperty->GetDisplayId() != defaultScreenId;
6463 }
6464 
CheckWindowModeType()6465 WindowModeType SceneSessionManager::CheckWindowModeType()
6466 {
6467     bool inSplit = false;
6468     bool inFloating = false;
6469     bool fullScreen = false;
6470     bool isSmallFold = IsSmallFoldProduct();
6471     {
6472         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6473         for (const auto& session : sceneSessionMap_) {
6474             if (session.second == nullptr ||
6475                 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
6476                 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
6477                 continue;
6478             }
6479             if (isSmallFold && IsInSecondaryScreen(session.second)) {
6480                 continue;
6481             }
6482             auto mode = session.second->GetWindowMode();
6483             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
6484                 inSplit = true;
6485             }
6486             if (mode == WindowMode::WINDOW_MODE_FLOATING) {
6487                 inFloating = true;
6488             }
6489             if (WindowHelper::IsFullScreenWindow(mode)) {
6490                 fullScreen = true;
6491             }
6492         }
6493     }
6494 
6495     WindowModeType type;
6496     if (inSplit) {
6497         if (inFloating) {
6498             type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
6499         } else {
6500             type = WindowModeType::WINDOW_MODE_SPLIT;
6501         }
6502     } else {
6503         if (inFloating) {
6504             if (fullScreen) {
6505                 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
6506             } else {
6507                 type = WindowModeType::WINDOW_MODE_FLOATING;
6508             }
6509         } else if (fullScreen) {
6510             type = WindowModeType::WINDOW_MODE_FULLSCREEN;
6511         } else {
6512             type = WindowModeType::WINDOW_MODE_OTHER;
6513         }
6514     }
6515     return type;
6516 }
6517 
NotifyRSSWindowModeTypeUpdate()6518 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
6519 {
6520     WindowModeType type = CheckWindowModeType();
6521     if (lastWindowModeType_ == type) {
6522         return;
6523     }
6524     lastWindowModeType_ = type;
6525     TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
6526         static_cast<uint8_t>(type));
6527     SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
6528 }
6529 
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)6530 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
6531 {
6532     if (sceneSession == nullptr) {
6533         WLOGFD("session is nullptr");
6534         return;
6535     }
6536     std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
6537     for (const auto& subSession : sceneSession->GetSubSession()) {
6538         if (subSession == nullptr) {
6539             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
6540             continue;
6541         }
6542         if (subSession->IsTopmost()) {
6543             modalVec.push_back(subSession);
6544             TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
6545             continue;
6546         }
6547         const auto& state = subSession->GetSessionState();
6548         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6549             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
6550             continue;
6551         }
6552         RequestSessionFocus(subSession->GetPersistentId(), true);
6553         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6554         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
6555     }
6556 
6557     for (const auto& modal : modalVec) {
6558         if (modal == nullptr) {
6559             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
6560             continue;
6561         }
6562         const auto& state = modal->GetSessionState();
6563         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6564             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
6565             continue;
6566         }
6567         auto modalSession = GetSceneSession(modal->GetPersistentId());
6568         if (modalSession == nullptr) {
6569             TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
6570             continue;
6571         }
6572         NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6573         if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
6574             needBlockNotifyUnfocusStatus_ = false;
6575             needBlockNotifyFocusStatusUntilForeground_ = false;
6576             NotifyFocusStatus(modalSession, true);
6577         }
6578         HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
6579     }
6580 }
6581 
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6582 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6583 {
6584     // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
6585     sptr<SceneSession> mainSession = nullptr;
6586     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6587         mainSession = sceneSession;
6588     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6589         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6590     }
6591     if (mainSession == nullptr) {
6592         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6593         return WSError::WS_DO_NOTHING;
6594     }
6595 
6596     std::vector<sptr<SceneSession>> topmostVec;
6597     for (auto subSession : mainSession->GetSubSession()) {
6598         if (subSession && subSession->IsTopmost()) {
6599             topmostVec.push_back(subSession);
6600         }
6601     }
6602     if (std::find_if(topmostVec.begin(), topmostVec.end(),
6603         [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6604         != topmostVec.end()) {
6605             TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
6606             return WSError::WS_OK;
6607     }
6608     WSError ret = WSError::WS_DO_NOTHING;
6609     for (auto topmostSession : topmostVec) {
6610         if (topmostSession == nullptr) {
6611             continue;
6612         }
6613         // no need to consider order, since rule of zOrder
6614         if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
6615             ret = WSError::WS_OK;
6616         }
6617     }
6618     return ret;
6619 }
6620 
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6621 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6622 {
6623     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
6624     sptr<SceneSession> mainSession = nullptr;
6625     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6626         mainSession = sceneSession;
6627     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6628         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6629     }
6630     if (mainSession == nullptr) {
6631         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6632         return WSError::WS_DO_NOTHING;
6633     }
6634     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
6635     if (std::find_if(dialogVec.begin(), dialogVec.end(),
6636         [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6637         != dialogVec.end()) {
6638             TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
6639             return WSError::WS_OK;
6640     }
6641     WSError ret = WSError::WS_DO_NOTHING;
6642     for (auto dialog : dialogVec) {
6643         if (dialog == nullptr) {
6644             continue;
6645         }
6646         // no need to consider order, since rule of zOrder
6647         if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
6648             ret = WSError::WS_OK;
6649         }
6650     }
6651     return ret;
6652 }
6653 
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)6654 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
6655 {
6656     if (sceneSession == nullptr) {
6657         WLOGFD("session is nullptr");
6658         return;
6659     }
6660     for (const auto& subSession : sceneSession->GetSubSession()) {
6661         if (subSession == nullptr) {
6662             WLOGFD("sub session is nullptr");
6663             continue;
6664         }
6665         const auto& state = subSession->GetSessionState();
6666         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6667             WLOGFD("sub session is not active");
6668             continue;
6669         }
6670         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6671         HandleKeepScreenOn(subSession, false);
6672         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
6673     }
6674     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
6675     for (const auto& dialog : dialogVec) {
6676         if (dialog == nullptr) {
6677             TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
6678             continue;
6679         }
6680         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
6681         if (dialogSession == nullptr) {
6682             TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
6683             continue;
6684         }
6685         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6686         HandleKeepScreenOn(dialogSession, false);
6687         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
6688     }
6689     for (const auto& toastSession : sceneSession->GetToastSession()) {
6690         if (toastSession == nullptr) {
6691             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
6692             continue;
6693         }
6694         const auto& state = toastSession->GetSessionState();
6695         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6696             continue;
6697         }
6698         NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6699         HandleKeepScreenOn(toastSession, false);
6700         UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
6701         toastSession->SetActive(false);
6702         toastSession->BackgroundTask();
6703     }
6704 }
6705 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)6706 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
6707     const sptr<WindowSessionProperty>& property)
6708 {
6709     if (sceneSession == nullptr) {
6710         WLOGFD("session is nullptr");
6711         return WSError::WS_ERROR_NULLPTR;
6712     }
6713     auto sessionProperty = sceneSession->GetSessionProperty();
6714     if (sessionProperty == nullptr) {
6715         return WSError::WS_ERROR_NULLPTR;
6716     }
6717     uint32_t flags = property->GetWindowFlags();
6718     uint32_t oldFlags = sessionProperty->GetWindowFlags();
6719     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6720         (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6721         !property->GetSystemCalling()) {
6722             WLOGFE("Set window flags permission denied");
6723             return WSError::WS_ERROR_NOT_SYSTEM_APP;
6724     }
6725     sessionProperty->SetWindowFlags(flags);
6726     CheckAndNotifyWaterMarkChangedResult();
6727     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6728         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6729     }
6730     WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
6731     return WSError::WS_OK;
6732 }
6733 
CheckAndNotifyWaterMarkChangedResult()6734 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
6735 {
6736     bool currentWaterMarkShowState = false;
6737     {
6738         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6739         for (const auto& iter: sceneSessionMap_) {
6740             auto& session = iter.second;
6741             if (!session) {
6742                 continue;
6743             }
6744             auto sessionProperty = session->GetSessionProperty();
6745             if (!sessionProperty) {
6746                 continue;
6747             }
6748             bool hasWaterMark = sessionProperty->GetWindowFlags() &
6749                 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
6750             bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
6751             if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
6752                 currentWaterMarkShowState = true;
6753                 break;
6754             }
6755         }
6756         if (combinedExtWindowFlags_.waterMarkFlag) {
6757             TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
6758             currentWaterMarkShowState = true;
6759         }
6760     }
6761     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
6762         lastWaterMarkShowState_ = currentWaterMarkShowState;
6763         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
6764     }
6765 }
6766 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)6767 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
6768 {
6769     WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
6770     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
6771     return WSError::WS_OK;
6772 }
6773 
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const6774 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
6775 {
6776     if (!bundleMgr_) {
6777         WLOGFE("bundle manager is nullptr.");
6778         return;
6779     }
6780 
6781     AAFwk::Want want;
6782     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
6783     auto uid = abilityInfo.uid;
6784     want.SetParam("uid", uid);
6785     bundleMgr_->ProcessPreload(want);
6786 }
6787 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)6788 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
6789 {
6790     auto scnSession = GetSceneSession(persistentId);
6791     if (scnSession == nullptr) {
6792         TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
6793         return;
6794     }
6795 
6796     const auto& sessionInfo = scnSession->GetSessionInfo();
6797     if (IsAtomicServiceFreeInstall(sessionInfo)) {
6798         TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
6799             scnSession->GetPersistentId(), scnSession->GetWindowType());
6800         FillSessionInfo(scnSession);
6801     }
6802 
6803     TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
6804         scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
6805         sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6806     auto abilityInfoPtr = sessionInfo.abilityInfo;
6807     if (abilityInfoPtr == nullptr) {
6808         TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
6809         return;
6810     }
6811     if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
6812         !(abilityInfoPtr->excludeFromMissions)) {
6813         WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
6814         listenerController_->NotifySessionCreated(persistentId);
6815     }
6816 
6817     if (eventHandler_ != nullptr) {
6818         auto task = [persistentId]() {
6819             AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6820         };
6821         WLOGFI("Post CompleteFirstFrameDrawing task.");
6822         bool ret = eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6823         if (!ret) {
6824             WLOGFE("Report post first frame task failed. the task name is CompleteFirstFrameDrawing");
6825         }
6826     }
6827 
6828     if (taskScheduler_ == nullptr) {
6829         return;
6830     }
6831     auto task = [this, abilityInfoPtr]() {
6832         ProcessPreload(*abilityInfoPtr);
6833     };
6834     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6835 }
6836 
NotifySessionMovedToFront(int32_t persistentId)6837 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6838 {
6839     WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
6840     auto scnSession = GetSceneSession(persistentId);
6841     if (scnSession == nullptr) {
6842         WLOGFE("session is invalid with %{public}d", persistentId);
6843         return;
6844     }
6845     WLOGFI("NotifySessionMovedToFront, id: %{public}d, system: %{public}d", scnSession->GetPersistentId(),
6846            scnSession->GetSessionInfo().isSystem_);
6847     if (listenerController_ != nullptr &&
6848         !scnSession->GetSessionInfo().isSystem_ &&
6849         (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
6850         !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6851         listenerController_->NotifySessionMovedToFront(persistentId);
6852     }
6853 }
6854 
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)6855 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6856 {
6857     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
6858     auto task = [this, &token, &label]() {
6859         auto sceneSession = FindSessionByToken(token);
6860         if (sceneSession == nullptr) {
6861             WLOGFI("fail to find session by token");
6862             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6863         }
6864         sceneSession->SetSessionLabel(label);
6865         WLOGFI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6866             sceneSession->GetSessionInfo().isSystem_);
6867         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
6868             WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6869             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6870         }
6871         return WSError::WS_OK;
6872     };
6873     return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6874 }
6875 
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)6876 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6877     const std::shared_ptr<Media::PixelMap>& icon)
6878 {
6879     WLOGFI("Enter");
6880     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6881         WLOGFE("The caller is not system-app, can not use system-api");
6882         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6883     }
6884 
6885     auto task = [this, &token, &icon]() {
6886         auto sceneSession = FindSessionByToken(token);
6887         if (sceneSession == nullptr) {
6888             WLOGFI("fail to find session by token");
6889             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6890         }
6891         sceneSession->SetSessionIcon(icon);
6892         WLOGFI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6893             sceneSession->GetSessionInfo().isSystem_);
6894         if (listenerController_ != nullptr &&
6895             !sceneSession->GetSessionInfo().isSystem_ &&
6896             (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
6897             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6898             WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6899             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6900         }
6901         return WSError::WS_OK;
6902     };
6903     return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6904 }
6905 
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)6906 WSError SceneSessionManager::IsValidSessionIds(
6907     const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6908 {
6909     WLOGFI("Enter");
6910     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6911     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6912         auto search = sceneSessionMap_.find(sessionIds.at(i));
6913         if (search == sceneSessionMap_.end() || search->second == nullptr) {
6914             results.push_back(false);
6915             continue;
6916         }
6917         results.push_back(true);
6918     }
6919     return WSError::WS_OK;
6920 }
6921 
RegisterSessionListener(const sptr<ISessionListener> & listener)6922 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6923 {
6924     WLOGFI("Enter");
6925     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6926         WLOGFE("The caller is not system-app, can not use system-api");
6927         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6928     }
6929     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6930         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6931         return WSError::WS_ERROR_INVALID_PERMISSION;
6932     }
6933     auto task = [this, &listener]() {
6934         WSError ret = WSError::WS_DO_NOTHING;
6935         if (listenerController_ != nullptr) {
6936             ret = listenerController_->AddSessionListener(listener);
6937         } else {
6938             WLOGFE("The listenerController is nullptr");
6939         }
6940 
6941         // app continue report for distributed scheduled service
6942         SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6943             static_cast<int32_t>(ret));
6944 
6945         return ret;
6946     };
6947     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6948 }
6949 
UnRegisterSessionListener(const sptr<ISessionListener> & listener)6950 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6951 {
6952     WLOGFI("Enter");
6953     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6954         WLOGFE("The caller is not system-app, can not use system-api");
6955         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6956     }
6957     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6958         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6959         return WSError::WS_ERROR_INVALID_PERMISSION;
6960     }
6961     auto task = [this, &listener]() {
6962         if (listenerController_ != nullptr) {
6963             listenerController_->DelSessionListener(listener);
6964             return WSError::WS_OK;
6965         } else {
6966             WLOGFE("The listenerController is nullptr");
6967             return WSError::WS_DO_NOTHING;
6968         }
6969     };
6970     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6971 }
6972 
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6973 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6974                                              std::vector<SessionInfoBean>& sessionInfos)
6975 {
6976     WLOGFI("Enter num max %{public}d", numMax);
6977     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6978         WLOGFE("The caller is not system-app, can not use system-api");
6979         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6980     }
6981     if (!SessionPermission::VerifySessionPermission()) {
6982         WLOGFE("The caller has not permission granted");
6983         return WSError::WS_ERROR_INVALID_PERMISSION;
6984     }
6985     auto task = [this, &deviceId, numMax, &sessionInfos]() {
6986         if (CheckIsRemote(deviceId)) {
6987             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6988             if (ret != ERR_OK) {
6989                 return WSError::WS_ERROR_INVALID_PARAM;
6990             } else {
6991                 return WSError::WS_OK;
6992             }
6993         }
6994         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6995         std::vector<sptr<SceneSession>> sceneSessionInfos;
6996         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6997         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6998             auto sceneSession = iter->second;
6999             if (sceneSession == nullptr) {
7000                 WLOGFE("session is nullptr");
7001                 continue;
7002             }
7003             auto sessionInfo = sceneSession->GetSessionInfo();
7004             if (sessionInfo.isSystem_) {
7005                 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
7006                 continue;
7007             }
7008             auto want = sessionInfo.want;
7009             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
7010                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
7011                     sceneSession->GetPersistentId());
7012                 continue;
7013             }
7014             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
7015                 break;
7016             }
7017             WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
7018                 sessionInfo.bundleName_.c_str());
7019             sceneSessionInfos.emplace_back(sceneSession);
7020         }
7021         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
7022     };
7023     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
7024 }
7025 
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)7026 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
7027 {
7028     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
7029     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
7030         TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
7031         return WSError::WS_ERROR_INVALID_PERMISSION;
7032     }
7033     if (pid < 0) {
7034         return WSError::WS_ERROR_INVALID_PARAM;
7035     }
7036     auto task = [this, pid, &windowStates] {
7037         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7038         for (const auto& [_, sceneSession] : sceneSessionMap_) {
7039             if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
7040                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7041                 MainWindowState windowState;
7042                 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
7043                 windowState.isVisible_ = sceneSession->GetRSVisible();
7044                 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
7045                 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
7046                 windowStates.emplace_back(windowState);
7047             }
7048         }
7049         return WSError::WS_OK;
7050     };
7051     return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
7052 }
7053 
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)7054 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
7055                                                std::vector<SessionInfoBean>& sessionInfos)
7056 {
7057     TLOGI(WmsLogTag::DEFAULT, "begin");
7058     int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
7059     if (result != ERR_OK) {
7060         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
7061         return result;
7062     }
7063     return ERR_OK;
7064 }
7065 
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)7066 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
7067                                             int32_t persistentId, SessionInfoBean& sessionInfo)
7068 {
7069     WLOGFI("id %{public}d", persistentId);
7070     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7071         WLOGFE("The caller is not system-app, can not use system-api");
7072         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7073     }
7074     if (!SessionPermission::VerifySessionPermission()) {
7075         WLOGFE("The caller has not permission granted");
7076         return WSError::WS_ERROR_INVALID_PERMISSION;
7077     }
7078     auto task = [this, &deviceId, persistentId, &sessionInfo]() {
7079         if (CheckIsRemote(deviceId)) {
7080             int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
7081             if (ret != ERR_OK) {
7082                 return WSError::WS_ERROR_INVALID_PARAM;
7083             } else {
7084                 return WSError::WS_OK;
7085             }
7086         }
7087         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7088         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7089         iter = sceneSessionMap_.find(persistentId);
7090         if (iter != sceneSessionMap_.end()) {
7091             auto sceneSession = iter->second;
7092             if (sceneSession == nullptr) {
7093                 WLOGFE("session: %{public}d is nullptr", persistentId);
7094                 return WSError::WS_ERROR_INVALID_PARAM;
7095             }
7096             auto sceneSessionInfo = sceneSession->GetSessionInfo();
7097             if (sceneSessionInfo.isSystem_) {
7098                 WLOGFD("sessionId: %{public}d  isSystemScene", persistentId);
7099                 return WSError::WS_ERROR_INVALID_PARAM;
7100             }
7101             auto want = sceneSessionInfo.want;
7102             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
7103                 want->GetElement().GetBundleName().empty()) {
7104                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
7105                     persistentId);
7106                 return WSError::WS_ERROR_INTERNAL_ERROR;
7107             }
7108             WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
7109                 sceneSessionInfo.bundleName_.c_str());
7110             return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
7111         } else {
7112             WLOGFW("sessionId: %{public}d not found", persistentId);
7113             return WSError::WS_ERROR_INVALID_PARAM;
7114         }
7115     };
7116     return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
7117 }
7118 
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)7119 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
7120     SessionInfoBean& sessionInfo)
7121 {
7122     TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
7123         continueSessionId.c_str());
7124     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7125         TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
7126         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7127     }
7128     if (!SessionPermission::VerifySessionPermission()) {
7129         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
7130         return WSError::WS_ERROR_INVALID_PERMISSION;
7131     }
7132     auto task = [this, continueSessionId, &sessionInfo]() {
7133         WSError ret = WSError::WS_ERROR_INVALID_SESSION;
7134         {
7135             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7136             for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
7137                 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
7138                     ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
7139                     break;
7140                 }
7141             }
7142         }
7143 
7144         TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
7145         // app continue report for distributed scheduled service
7146         SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
7147             static_cast<int32_t>(ret));
7148         return ret;
7149     };
7150     return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
7151 }
7152 
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)7153 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
7154                                               int32_t persistentId, SessionInfoBean& sessionInfo)
7155 {
7156     WLOGFI("GetRemoteSessionInfoFromDms begin");
7157     std::vector<SessionInfoBean> sessionVector;
7158     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
7159     if (result != ERR_OK) {
7160         return result;
7161     }
7162     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
7163         if (iter->id == persistentId) {
7164             sessionInfo = *iter;
7165             return ERR_OK;
7166         }
7167     }
7168     WLOGFW("missionId not found");
7169     return ERR_INVALID_VALUE;
7170 }
7171 
CheckIsRemote(const std::string & deviceId)7172 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
7173 {
7174     if (deviceId.empty()) {
7175         WLOGFI("CheckIsRemote: deviceId is empty.");
7176         return false;
7177     }
7178     std::string localDeviceId;
7179     if (!GetLocalDeviceId(localDeviceId)) {
7180         WLOGFE("CheckIsRemote: get local deviceId failed");
7181         return false;
7182     }
7183     if (localDeviceId == deviceId) {
7184         WLOGFI("CheckIsRemote: deviceId is local.");
7185         return false;
7186     }
7187     WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
7188     return true;
7189 }
7190 
GetLocalDeviceId(std::string & localDeviceId)7191 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
7192 {
7193     auto localNode = std::make_unique<NodeBasicInfo>();
7194     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
7195     if (errCode != ERR_OK) {
7196         WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
7197         return false;
7198     }
7199     if (localNode != nullptr) {
7200         localDeviceId = localNode->networkId;
7201         WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
7202         return true;
7203     }
7204     WLOGFE("localDeviceId null");
7205     return false;
7206 }
7207 
AnonymizeDeviceId(const std::string & deviceId)7208 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
7209 {
7210     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
7211         return EMPTY_DEVICE_ID;
7212     }
7213     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
7214     anonDeviceId.append("******");
7215     return anonDeviceId;
7216 }
7217 
DumpSessionAll(std::vector<std::string> & infos)7218 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
7219 {
7220     WLOGFI("Dump all session.");
7221     if (!SessionPermission::IsSystemCalling()) {
7222         WLOGFE("DumpSessionAll permission denied!");
7223         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7224     }
7225 
7226     auto task = [this, &infos]() {
7227         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
7228         infos.push_back(dumpInfo);
7229         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7230         for (const auto &item : sceneSessionMap_) {
7231             auto& session = item.second;
7232             if (session) {
7233                 session->DumpSessionInfo(infos);
7234             }
7235         }
7236         return WSError::WS_OK;
7237     };
7238 
7239     return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
7240 }
7241 
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)7242 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
7243 {
7244     WLOGFI("Dump session with id %{public}d", persistentId);
7245     if (!SessionPermission::IsSystemCalling()) {
7246         WLOGFE("DumpSessionWithId permission denied!");
7247         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7248     }
7249 
7250     auto task = [this, persistentId, &infos]() {
7251         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
7252         infos.push_back(dumpInfo);
7253         auto session = GetSceneSession(persistentId);
7254         if (session) {
7255             session->DumpSessionInfo(infos);
7256         } else {
7257             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
7258         }
7259         return WSError::WS_OK;
7260     };
7261 
7262     return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
7263 }
7264 
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)7265 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
7266     const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
7267 {
7268     if (bundleMgr_ == nullptr) {
7269         WLOGFE("bundleMgr_ is nullptr");
7270         return WSError::WS_ERROR_NULLPTR;
7271     }
7272     auto elementName = want.GetElement();
7273     int32_t ret{0};
7274     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
7275         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
7276         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
7277         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
7278         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
7279         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
7280     std::vector<AppExecFwk::BundleInfo> bundleInfos;
7281     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
7282         WLOGFD("want is empty queryAllAbilityInfos");
7283         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
7284         if (ret) {
7285             WLOGFE("Query all ability infos from BMS failed!");
7286             return WSError::WS_ERROR_INVALID_PARAM;
7287         }
7288     } else if (!elementName.GetBundleName().empty()) {
7289         AppExecFwk::BundleInfo bundleInfo;
7290         WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
7291         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
7292         if (ret) {
7293             WLOGFE("Query ability info from BMS failed!");
7294             return WSError::WS_ERROR_INVALID_PARAM;
7295         }
7296         bundleInfos.push_back(bundleInfo);
7297     } else {
7298         WLOGFE("invalid want:%{public}s", want.ToString().c_str());
7299         return WSError::WS_ERROR_INVALID_PARAM;
7300     }
7301     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
7302 }
7303 
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)7304 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
7305     const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
7306 {
7307     if (bundleMgr_ == nullptr) {
7308         TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
7309         return WSError::WS_ERROR_NULLPTR;
7310     }
7311     if (bundleNames.empty()) {
7312         TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
7313         return WSError::WS_ERROR_INVALID_PARAM;
7314     }
7315     auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
7316                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
7317                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
7318                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
7319                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
7320                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
7321     std::vector<AppExecFwk::BundleInfo> bundleInfos;
7322     auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
7323     if (ret) {
7324         TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
7325         return WSError::WS_ERROR_INVALID_PARAM;
7326     }
7327     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
7328 }
7329 
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)7330 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
7331     const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
7332 {
7333     if (bundleMgr_ == nullptr) {
7334         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
7335         return WSError::WS_ERROR_NULLPTR;
7336     }
7337     auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
7338         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
7339         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
7340         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
7341         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
7342         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
7343     AppExecFwk::BundleInfo bundleInfo;
7344     if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
7345         TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
7346         return WSError::WS_ERROR_INVALID_PARAM;
7347     }
7348     auto& hapModulesList = bundleInfo.hapModuleInfos;
7349     if (hapModulesList.empty()) {
7350         TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
7351         return WSError::WS_ERROR_INVALID_PARAM;
7352     }
7353     auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
7354     for (auto& hapModule : hapModulesList) {
7355         auto& abilityInfoList = hapModule.abilityInfos;
7356         for (auto& abilityInfo : abilityInfoList) {
7357             if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
7358                 scbAbilityInfo.abilityInfo_ = abilityInfo;
7359                 scbAbilityInfo.sdkVersion_ = sdkVersion;
7360                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
7361                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
7362                 return WSError::WS_OK;
7363             }
7364         }
7365     }
7366     TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
7367     return WSError::WS_ERROR_INVALID_PARAM;
7368 }
7369 
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)7370 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
7371     std::vector<SCBAbilityInfo>& scbAbilityInfos)
7372 {
7373     if (bundleInfos.empty()) {
7374         WLOGFE("bundleInfos is empty");
7375         return WSError::WS_ERROR_INVALID_PARAM;
7376     }
7377     for (auto& bundleInfo : bundleInfos) {
7378         auto& hapModulesList = bundleInfo.hapModuleInfos;
7379         auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
7380         if (hapModulesList.empty()) {
7381             WLOGFD("hapModulesList is empty");
7382             continue;
7383         }
7384         if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
7385             bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
7386             auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
7387                 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
7388             if (iter != hapModulesList.end()) {
7389                 SCBAbilityInfo scbAbilityInfo;
7390                 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
7391                 scbAbilityInfo.sdkVersion_ = sdkVersion;
7392                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
7393                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
7394                 scbAbilityInfos.push_back(scbAbilityInfo);
7395                 continue;
7396             }
7397         }
7398         for (auto& hapModule : hapModulesList) {
7399             auto& abilityInfoList = hapModule.abilityInfos;
7400             for (auto& abilityInfo : abilityInfoList) {
7401                 SCBAbilityInfo scbAbilityInfo;
7402                 scbAbilityInfo.abilityInfo_ = abilityInfo;
7403                 scbAbilityInfo.sdkVersion_ = sdkVersion;
7404                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
7405                 scbAbilityInfos.push_back(scbAbilityInfo);
7406             }
7407         }
7408     }
7409     return WSError::WS_OK;
7410 }
7411 
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)7412 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
7413 {
7414     if (abilityInfo.orientationId == 0) {
7415         return;
7416     }
7417     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
7418     if (resConfig == nullptr) {
7419         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
7420         return;
7421     }
7422     std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
7423         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
7424     if (resourceMgr == nullptr) {
7425         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
7426         return;
7427     }
7428     std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
7429     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
7430         TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
7431     }
7432     std::string orientation;
7433     auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
7434     if (ret != Global::Resource::RState::SUCCESS) {
7435         TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
7436             static_cast<int32_t>(ret), abilityInfo.orientationId);
7437         return;
7438     }
7439     if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
7440         TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
7441         return;
7442     }
7443     abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
7444 }
7445 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)7446 WSError SceneSessionManager::TerminateSessionNew(
7447     const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
7448 {
7449     if (info == nullptr) {
7450         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
7451         return WSError::WS_ERROR_INVALID_PARAM;
7452     }
7453     TLOGI(WmsLogTag::WMS_LIFE,
7454         "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
7455         info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
7456     int32_t callingPid = IPCSkeleton::GetCallingPid();
7457     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
7458     auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
7459         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
7460         if (sceneSession == nullptr) {
7461             TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
7462             return WSError::WS_ERROR_INVALID_PARAM;
7463         }
7464         const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
7465         if (!pidCheck &&
7466             !SessionPermission::VerifyPermissionByCallerToken(callerToken,
7467                 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7468             TLOGE(WmsLogTag::WMS_LIFE,
7469                 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
7470                 sceneSession->GetCallingPid(), callingPid);
7471             return WSError::WS_ERROR_INVALID_PERMISSION;
7472         }
7473         WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
7474         return errCode;
7475     };
7476     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
7477 }
7478 
SetVmaCacheStatus(bool flag)7479 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
7480 {
7481     WLOGFI("flag: %{public}d", flag);
7482     RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
7483     return WSError::WS_OK;
7484 }
7485 
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)7486 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
7487                                                 SessionSnapshot& snapshot, bool isLowResolution)
7488 {
7489     WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
7490     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7491         WLOGFE("The caller is not system-app, can not use system-api");
7492         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7493     }
7494     if (!SessionPermission::VerifySessionPermission()) {
7495         WLOGFE("The caller has not permission granted");
7496         return WSError::WS_ERROR_INVALID_PERMISSION;
7497     }
7498     auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
7499         if (CheckIsRemote(deviceId)) {
7500             int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
7501             if (ret != ERR_OK) {
7502                 return WSError::WS_ERROR_INVALID_PARAM;
7503             } else {
7504                 return WSError::WS_OK;
7505             }
7506         }
7507         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7508         if (!sceneSession) {
7509             return WSError::WS_ERROR_INVALID_PARAM;
7510         }
7511         auto sessionInfo = sceneSession->GetSessionInfo();
7512         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7513             WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7514                    sceneSession->GetPersistentId());
7515         }
7516         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
7517         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
7518         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
7519         auto oriSnapshot = sceneSession->Snapshot();
7520         if (oriSnapshot != nullptr) {
7521             if (isLowResolution) {
7522                 OHOS::Media::InitializationOptions options;
7523                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
7524                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
7525                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap
7526                     = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
7527                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
7528             } else {
7529                 snapshot.snapshot = oriSnapshot;
7530             }
7531         }
7532         return WSError::WS_OK;
7533     };
7534     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
7535 }
7536 
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)7537 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
7538 {
7539     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
7540         TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
7541         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7542     }
7543     auto task = [this, persistentId, &snapshot]() {
7544         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7545         if (!sceneSession) {
7546             TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
7547             return WMError::WM_ERROR_INVALID_PARAM;
7548         }
7549         auto sessionInfo = sceneSession->GetSessionInfo();
7550         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7551             TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7552                 sceneSession->GetPersistentId());
7553         }
7554         snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
7555         snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
7556         snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
7557         float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
7558         auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale);
7559         if (oriSnapshot != nullptr) {
7560             if (sceneSession->GetFloatingScale() > 1.0f) {
7561                 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
7562             }
7563             snapshot.snapshot = oriSnapshot;
7564             TLOGI(WmsLogTag::WMS_SYSTEM, "snapshot WxH = %{public}dx%{public}d",
7565                 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
7566             return WMError::WM_OK;
7567         }
7568         return WMError::WM_ERROR_NULLPTR;
7569     };
7570     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
7571 }
7572 
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)7573 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
7574 {
7575     if (!SessionPermission::IsSACalling()) {
7576         TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
7577         return WSError::WS_ERROR_INVALID_PERMISSION;
7578     }
7579     TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
7580     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7581     if (sceneSession == nullptr) {
7582         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
7583         return WSError::WS_ERROR_NULLPTR;
7584     }
7585     return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
7586 }
7587 
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)7588 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
7589                                                       AAFwk::MissionSnapshot& sessionSnapshot)
7590 {
7591     TLOGI(WmsLogTag::DEFAULT, "begin");
7592     int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
7593         sessionId, sessionSnapshot);
7594     if (result != ERR_OK) {
7595         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
7596         return result;
7597     }
7598     return ERR_OK;
7599 }
7600 
GetCollaboratorByType(int32_t collaboratorType)7601 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
7602 {
7603     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
7604     std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
7605     auto iter = collaboratorMap_.find(collaboratorType);
7606     if (iter == collaboratorMap_.end()) {
7607         TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
7608         return collaborator;
7609     }
7610     collaborator = iter->second;
7611     if (collaborator == nullptr) {
7612         TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
7613     }
7614     return collaborator;
7615 }
7616 
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)7617 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
7618 {
7619     wptr<SceneSession> weakSceneSession(sceneSession);
7620     auto task = [this, weakSceneSession]() {
7621         auto scnSession = weakSceneSession.promote();
7622         if (scnSession == nullptr) {
7623             WLOGFE("session is nullptr");
7624             return WSError::WS_ERROR_NULLPTR;
7625         }
7626         auto persistentId = scnSession->GetPersistentId();
7627         if (!GetSceneSession(persistentId)) {
7628             WLOGFE("session is invalid with %{public}d", persistentId);
7629             return WSError::WS_ERROR_INVALID_SESSION;
7630         }
7631         auto sessionInfo = scnSession->GetSessionInfo();
7632         auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
7633         if (!abilitySessionInfo) {
7634             TLOGE(WmsLogTag::WMS_MAIN,
7635                 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
7636             return WSError::WS_ERROR_NULLPTR;
7637         }
7638         TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
7639             sessionInfo.callState_, persistentId);
7640         bool isColdStart = false;
7641         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
7642         if (isColdStart) {
7643             TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
7644                 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
7645             scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
7646             scnSession->ResetSessionConnectState();
7647         }
7648         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
7649         return WSError::WS_OK;
7650     };
7651     std::string taskName = "RequestSceneSessionByCall:PID:" +
7652         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
7653     taskScheduler_->PostAsyncTask(task, taskName);
7654     return WSError::WS_OK;
7655 }
7656 
StartAbilityBySpecified(const SessionInfo & sessionInfo)7657 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
7658 {
7659     auto task = [this, sessionInfo]() {
7660         WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
7661             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
7662         AAFwk::Want want;
7663         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
7664         if (sessionInfo.want != nullptr) {
7665             want.SetParams(sessionInfo.want->GetParams());
7666         }
7667         AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
7668     };
7669 
7670     taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
7671 }
7672 
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)7673 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
7674 {
7675     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
7676     if (pid == -1) {
7677         TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
7678         return;
7679     }
7680     int32_t ret = HiSysEventWrite(
7681         HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
7682         "WINDOW_STATE_ERROR",
7683         HiviewDFX::HiSysEvent::EventType::FAULT,
7684         "PID", pid,
7685         "PERSISTENT_ID", persistentId);
7686     if (ret != 0) {
7687         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
7688     }
7689     auto task = [this, pid] {
7690         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7691         for (const auto& [_, sceneSession] : sceneSessionMap_) {
7692             if (!sceneSession || pid != sceneSession->GetCallingPid() ||
7693                 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7694                 continue;
7695             }
7696             auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
7697             if (abilitySessionInfo) {
7698                 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
7699                     abilitySessionInfo->persistentId);
7700                 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
7701             }
7702         }
7703     };
7704     // delay 2000ms, wait for hidumper
7705     taskScheduler_->PostAsyncTask(task, __func__, 2000);
7706 }
7707 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)7708 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
7709 {
7710     if (!targetToken) {
7711         WLOGFE("Token is null, cannot find main window");
7712         return nullptr;
7713     }
7714 
7715     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7716     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
7717         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7718             if (pair.second->IsTerminated()) {
7719                 return false;
7720             }
7721             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7722                 return pair.second->GetAbilityToken() == targetToken;
7723             }
7724             return false;
7725         });
7726     if (iter == sceneSessionMap_.end()) {
7727         WLOGFE("Cannot find session");
7728         return nullptr;
7729     }
7730     return iter->second;
7731 }
7732 
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)7733 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
7734 {
7735     if (!SessionPermission::IsSystemCalling()) {
7736         TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
7737         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7738     }
7739     if (targetToken == nullptr) {
7740         TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
7741         return WSError::WS_ERROR_NULLPTR;
7742     }
7743 
7744     auto task = [this, persistentId, targetToken]() {
7745         auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
7746         if (scnSession == nullptr) {
7747             TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
7748             return WSError::WS_ERROR_NULLPTR;
7749         }
7750         if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
7751             TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
7752             return WSError::WS_OK;
7753         }
7754         scnSession->dialogTargetToken_ = targetToken;
7755         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
7756         if (parentSession == nullptr) {
7757             scnSession->NotifyDestroy();
7758             return WSError::WS_ERROR_INVALID_PARAM;
7759         }
7760         scnSession->SetParentSession(parentSession);
7761         scnSession->SetParentPersistentId(parentSession->GetPersistentId());
7762         UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
7763         TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
7764             persistentId, parentSession->GetPersistentId());
7765         return WSError::WS_OK;
7766     };
7767     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
7768 }
7769 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7770 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7771     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7772 {
7773     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
7774 }
7775 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7776 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7777     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7778 {
7779     auto isSaCall = SessionPermission::IsSACalling();
7780     if (!isSaCall) {
7781         WLOGFE("The interface only support for sa call");
7782         return WMError::WM_ERROR_INVALID_PERMISSION;
7783     }
7784     auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
7785         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7786         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7787         for (auto missionId : missionIds) {
7788             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
7789             if (iter == sceneSessionMap_.end()) {
7790                 continue;
7791             }
7792             auto sceneSession = iter->second;
7793             if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
7794                 continue;
7795             }
7796             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
7797             if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
7798                 surfaceNodeIds.push_back(missionId);
7799                 continue;
7800             }
7801             if (sceneSession->GetLeashWinSurfaceNode()) {
7802                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
7803             }
7804         }
7805         return WMError::WM_OK;
7806     };
7807     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
7808 }
7809 
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7810 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
7811     const sptr<IWindowManagerAgent>& windowManagerAgent)
7812 {
7813     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7814         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7815         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7816         if (!SessionPermission::IsSystemCalling()) {
7817             WLOGFE("RegisterWindowManagerAgent permission denied!");
7818             return WMError::WM_ERROR_NOT_SYSTEM_APP;
7819         }
7820     } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
7821         if (!SessionPermission::IsSystemServiceCalling()) {
7822             return WMError::WM_ERROR_INVALID_PERMISSION;
7823         }
7824     }
7825     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7826         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7827         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7828         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7829         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7830         if (!SessionPermission::IsSACalling()) {
7831             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7832             return WMError::WM_ERROR_INVALID_PERMISSION;
7833         }
7834     }
7835     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7836         WLOGFE("windowManagerAgent is null");
7837         return WMError::WM_ERROR_NULLPTR;
7838     }
7839     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7840     auto task = [this, windowManagerAgent, type, callingPid]() {
7841         return SessionManagerAgentController::GetInstance()
7842             .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7843     };
7844     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
7845 }
7846 
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7847 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
7848     const sptr<IWindowManagerAgent>& windowManagerAgent)
7849 {
7850     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7851         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7852         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7853         if (!SessionPermission::IsSystemCalling()) {
7854             WLOGFE("UnregisterWindowManagerAgent permission denied!");
7855             return WMError::WM_ERROR_NOT_SYSTEM_APP;
7856         }
7857     }
7858     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7859         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7860         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7861         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7862         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7863         if (!SessionPermission::IsSACalling()) {
7864             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7865             return WMError::WM_ERROR_INVALID_PERMISSION;
7866         }
7867     }
7868     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7869         WLOGFE("windowManagerAgent is null");
7870         return WMError::WM_ERROR_NULLPTR;
7871     }
7872     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7873     auto task = [this, windowManagerAgent, type, callingPid]() {
7874         return SessionManagerAgentController::GetInstance()
7875             .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7876     };
7877     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7878 }
7879 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)7880 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7881 {
7882     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7883 }
7884 
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)7885 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7886 {
7887     SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7888 }
7889 
StartWindowInfoReportLoop()7890 void SceneSessionManager::StartWindowInfoReportLoop()
7891 {
7892     WLOGFD("Report loop");
7893     if (eventHandler_ == nullptr) {
7894         WLOGFE("Report event null");
7895         return ;
7896     }
7897     if (isReportTaskStart_) {
7898         WLOGFE("Report is ReportTask Start");
7899         return;
7900     }
7901     auto task = [this]() {
7902         WindowInfoReporter::GetInstance().ReportRecordedInfos();
7903         ReportWindowProfileInfos();
7904         isReportTaskStart_ = false;
7905         StartWindowInfoReportLoop();
7906     };
7907     int64_t delayTime = 1000 * 60 * 60; // an hour.
7908     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7909     if (!ret) {
7910         WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
7911         return;
7912     }
7913     isReportTaskStart_ = true;
7914 }
7915 
InitPersistentStorage()7916 void SceneSessionManager::InitPersistentStorage()
7917 {
7918     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7919         int32_t storageMode = -1;
7920         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7921         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7922             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7923             WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7924             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7925         }
7926     }
7927 }
7928 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)7929 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7930 {
7931     WLOGFD("Called.");
7932     if (!SessionPermission::IsSystemServiceCalling()) {
7933         WLOGFE("Only support for system service.");
7934         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7935     }
7936     auto task = [this, &infos]() {
7937         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7938         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7939         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7940             sptr<SceneSession> sceneSession = iter->second;
7941             if (sceneSession == nullptr) {
7942                 WLOGFW("null scene session");
7943                 continue;
7944             }
7945             bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7946                 sceneSession->IsVisibleForAccessibility() :
7947                 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7948             WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7949                 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7950                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7951                 sceneSession->GetSessionState(), isVisibleForAccessibility);
7952             if (isVisibleForAccessibility) {
7953                 FillWindowInfo(infos, iter->second);
7954             }
7955         }
7956         return WMError::WM_OK;
7957     };
7958     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7959 }
7960 
CheckUnreliableWindowType(WindowType windowType)7961 static bool CheckUnreliableWindowType(WindowType windowType)
7962 {
7963     if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7964         windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7965         windowType == WindowType::WINDOW_TYPE_TOAST) {
7966         return true;
7967     }
7968     TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7969     return false;
7970 }
7971 
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)7972 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7973     std::vector<sptr<UnreliableWindowInfo>>& infos)
7974 {
7975     if (sceneSession == nullptr) {
7976         TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7977         return;
7978     }
7979     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7980         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7981         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7982         TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7983         return;
7984     }
7985     sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo();
7986     if (info == nullptr) {
7987         TLOGE(WmsLogTag::DEFAULT, "null info.");
7988         return;
7989     }
7990     info->windowId_ = sceneSession->GetPersistentId();
7991     WSRect windowRect = sceneSession->GetSessionRect();
7992     info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7993     info->zOrder_ = sceneSession->GetZOrder();
7994     info->floatingScale_ = sceneSession->GetFloatingScale();
7995     info->scaleX_ = sceneSession->GetScaleX();
7996     info->scaleY_ = sceneSession->GetScaleY();
7997     infos.emplace_back(info);
7998     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7999 }
8000 
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)8001 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
8002     std::vector<sptr<UnreliableWindowInfo>>& infos)
8003 {
8004     TLOGD(WmsLogTag::DEFAULT, "Called.");
8005     if (!SessionPermission::IsSystemServiceCalling()) {
8006         TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
8007         return WMError::WM_ERROR_NOT_SYSTEM_APP;
8008     }
8009     auto task = [this, windowId, &infos]() {
8010         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8011         for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
8012             if (sceneSession == nullptr) {
8013                 TLOGW(WmsLogTag::DEFAULT, "null scene session");
8014                 continue;
8015             }
8016             if (sessionId == windowId) {
8017                 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
8018                 FillUnreliableWindowInfo(sceneSession, infos);
8019                 continue;
8020             }
8021             if (!sceneSession->GetRSVisible()) {
8022                 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
8023                 continue;
8024             }
8025             TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
8026                 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
8027                 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
8028                 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
8029             if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
8030                 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
8031                     "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
8032                 FillUnreliableWindowInfo(sceneSession, infos);
8033             }
8034         }
8035         return WMError::WM_OK;
8036     };
8037     return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
8038 }
8039 
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)8040 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
8041 {
8042     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
8043     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8044     if (sceneSession == nullptr) {
8045         WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
8046         return;
8047     }
8048     wptr<SceneSession> weakSceneSession(sceneSession);
8049     if (processingFlushUIParams_.load()) {
8050         TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
8051         auto task = [this, weakSceneSession, type]() {
8052             auto sceneSession = weakSceneSession.promote();
8053             if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8054                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8055                 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8056             }
8057         };
8058         taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
8059         return;
8060     }
8061     auto task = [this, weakSceneSession, type]() {
8062         auto sceneSession = weakSceneSession.promote();
8063         NotifyAllAccessibilityInfo();
8064         if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
8065             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
8066             WindowChangedFunc_(sceneSession->GetPersistentId(), type);
8067         }
8068     };
8069     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:id:" + std::to_string(persistentId));
8070 
8071     auto notifySceneInputTask = [weakSceneSession, type]() {
8072         auto sceneSession = weakSceneSession.promote();
8073         if (sceneSession == nullptr) {
8074             return;
8075         }
8076         SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
8077     };
8078     taskScheduler_->PostAsyncTask(notifySceneInputTask);
8079 }
8080 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)8081 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
8082     const sptr<SceneSession>& sceneSession)
8083 {
8084     if (sceneSession == nullptr) {
8085         WLOGFW("null scene session.");
8086         return false;
8087     }
8088     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
8089         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
8090         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
8091         WLOGFD("filter gesture window.");
8092         return false;
8093     }
8094     sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
8095     if (info == nullptr) {
8096         WLOGFE("null info.");
8097         return false;
8098     }
8099     if (sceneSession->GetSessionInfo().isSystem_) {
8100         info->wid_ = 1;
8101         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
8102     } else {
8103         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
8104     }
8105     info->uiNodeId_ = sceneSession->GetUINodeId();
8106     WSRect wsRect = sceneSession->GetSessionGlobalRectWithSingleHandScale(); // only accessability and mmi need global
8107     info->windowRect_ = { wsRect.posX_, wsRect.posY_, wsRect.width_, wsRect.height_ };
8108     info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
8109     info->type_ = sceneSession->GetWindowType();
8110     info->mode_ = sceneSession->GetWindowMode();
8111     info->layer_ = sceneSession->GetZOrder();
8112     info->scaleVal_ = sceneSession->GetFloatingScale();
8113     info->scaleX_ = sceneSession->GetScaleX();
8114     info->scaleY_ = sceneSession->GetScaleY();
8115     info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
8116     info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
8117     auto property = sceneSession->GetSessionProperty();
8118     if (property != nullptr) {
8119         info->displayId_ = property->GetDisplayId();
8120         info->isDecorEnable_ = property->IsDecorEnable();
8121     }
8122     infos.emplace_back(info);
8123     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
8124         info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
8125     return true;
8126 }
8127 
GetSessionSnapshotFilePath(int32_t persistentId)8128 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
8129 {
8130     WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
8131     auto sceneSession = GetSceneSession(persistentId);
8132     if (sceneSession == nullptr) {
8133         WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
8134         return "";
8135     }
8136     wptr<SceneSession> weakSceneSession(sceneSession);
8137     auto task = [this, weakSceneSession]() {
8138         auto scnSession = weakSceneSession.promote();
8139         if (scnSession == nullptr) {
8140             WLOGFE("session is nullptr");
8141             return std::string("");
8142         }
8143         std::string filePath = scnSession->GetSessionSnapshotFilePath();
8144         return filePath;
8145     };
8146     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
8147 }
8148 
SelectSesssionFromMap(const uint64_t & surfaceId)8149 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
8150 {
8151     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8152     for (const auto &item : sceneSessionMap_) {
8153         auto sceneSession = item.second;
8154         if (sceneSession == nullptr) {
8155             continue;
8156         }
8157         if (sceneSession->GetSurfaceNode() == nullptr) {
8158             continue;
8159         }
8160         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
8161             return sceneSession;
8162         }
8163     }
8164     return nullptr;
8165 }
8166 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)8167 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
8168 {
8169     WLOGFD("WindowLayerInfoChangeCallback: entry");
8170     std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
8171 
8172     auto task = [this, weak]() {
8173         auto weakOcclusionData = weak.lock();
8174         if (weakOcclusionData == nullptr) {
8175             WLOGFE("weak occlusionData is nullptr");
8176             return;
8177         }
8178         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
8179         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
8180         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
8181         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
8182         if (currVisibleData.size() != 0) {
8183             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
8184         }
8185         if (visibilityChangeInfos.size() != 0) {
8186             DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
8187             CacVisibleWindowNum();
8188         }
8189 
8190         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
8191         if (currDrawingContentData.size() != 0) {
8192             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
8193         }
8194         if (drawingContentChangeInfos.size() != 0) {
8195             DealwithDrawingContentChange(drawingContentChangeInfos);
8196         }
8197     };
8198     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
8199 }
8200 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)8201 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
8202     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
8203     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
8204 {
8205     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
8206     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
8207         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
8208         switch (windowLayerState) {
8209             case WINDOW_ALL_VISIBLE:
8210             case WINDOW_SEMI_VISIBLE:
8211             case WINDOW_IN_VISIBLE:
8212                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
8213                 break;
8214             case WINDOW_LAYER_DRAWING:
8215                 currDrawingContentData.emplace_back(iter->first, true);
8216                 break;
8217             case WINDOW_LAYER_NO_DRAWING:
8218                 currDrawingContentData.emplace_back(iter->first, false);
8219                 break;
8220             default:
8221                 break;
8222         }
8223     }
8224 }
8225 
UpdateSubWindowVisibility(const sptr<SceneSession> & session,WindowVisibilityState visibleState,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8226 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
8227     WindowVisibilityState visibleState,
8228     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
8229     std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
8230     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8231 {
8232     if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
8233             visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8234         auto subSessions = GetSubSceneSession(session->GetWindowId());
8235         if (subSessions.empty()) {
8236             return;
8237         }
8238 
8239         RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
8240 
8241         for (const auto& subSession : subSessions) {
8242             if (subSession == nullptr) {
8243                 continue;
8244             }
8245             if (session->GetCallingPid() != subSession->GetCallingPid() &&
8246                 (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData))) {
8247                 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
8248                     subSession->GetWindowId());
8249                 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
8250             }
8251         }
8252     }
8253 }
8254 
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8255 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
8256     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8257 {
8258     bool sessionRSVisible = false;
8259     for (const auto& elem : currVisibleData) {
8260         uint64_t surfaceId = elem.first;
8261         WindowVisibilityState visibleState = elem.second;
8262         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
8263         sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
8264         if (visibilitySession == nullptr) {
8265             continue;
8266         }
8267         if (session->GetWindowId() == visibilitySession->GetWindowId()) {
8268             if (isVisible) {
8269                 sessionRSVisible = true;
8270             }
8271             break;
8272         }
8273     }
8274     return sessionRSVisible;
8275 }
8276 
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)8277 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
8278     WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
8279     std::string& visibilityInfo)
8280 {
8281     if (session == nullptr) {
8282         TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
8283         return;
8284     }
8285     session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8286     session->SetVisibilityState(visibleState);
8287     int32_t windowId = session->GetWindowId();
8288     if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
8289         session->NotifyWindowVisibility();
8290     }
8291     windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
8292         windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
8293 
8294     visibilityInfo +=
8295         "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
8296 }
8297 
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)8298 void SceneSessionManager::RemoveDuplicateSubSession(
8299     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
8300     std::vector<sptr<SceneSession>>& subSessions)
8301 {
8302     for (const auto& elem : visibilityChangeInfo) {
8303         uint64_t surfaceId = elem.first;
8304         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8305         if (session == nullptr) {
8306             continue;
8307         }
8308         for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
8309             auto subSession = *iterator;
8310             if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
8311                 iterator = subSessions.erase(iterator);
8312             } else {
8313                 ++iterator;
8314             }
8315         }
8316     }
8317 }
8318 
GetSubSceneSession(int32_t parentWindowId)8319 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
8320 {
8321     std::vector<sptr<SceneSession>> subSessions;
8322     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8323     for (const auto& iter : sceneSessionMap_) {
8324         auto sceneSession = iter.second;
8325         if (sceneSession == nullptr) {
8326             continue;
8327         }
8328         if (sceneSession->GetParentSession() != nullptr &&
8329             sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
8330             subSessions.push_back(sceneSession);
8331         }
8332     }
8333     return subSessions;
8334 }
8335 
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8336 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
8337     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8338 {
8339     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
8340     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
8341     uint32_t i, j;
8342     i = j = 0;
8343     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
8344         if (lastVisibleData_[i].first < currVisibleData[j].first) {
8345             if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8346                 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8347             }
8348             i++;
8349         } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
8350             if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8351                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
8352             }
8353             j++;
8354         } else {
8355             if (lastVisibleData_[i].second != currVisibleData[j].second) {
8356                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
8357             }
8358             i++;
8359             j++;
8360         }
8361     }
8362     for (; i < lastVisibleData_.size(); ++i) {
8363         if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8364             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8365         }
8366     }
8367     for (; j < currVisibleData.size(); ++j) {
8368         if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
8369             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
8370         }
8371     }
8372     lastVisibleData_ = currVisibleData;
8373     return visibilityChangeInfo;
8374 }
8375 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)8376 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
8377     visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
8378 {
8379     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8380 #ifdef MEMMGR_WINDOW_ENABLE
8381     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
8382 #endif
8383 
8384     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
8385     for (const auto& elem : visibilityChangeInfo) {
8386         uint64_t surfaceId = elem.first;
8387         WindowVisibilityState visibleState = elem.second;
8388         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
8389         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8390         if (session == nullptr) {
8391             continue;
8392         }
8393         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
8394             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
8395             if (session->GetParentSession() != nullptr &&
8396                 !session->GetParentSession()->IsSessionForeground() &&
8397                 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
8398                 continue;
8399             }
8400         }
8401         SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
8402         UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
8403 #ifdef MEMMGR_WINDOW_ENABLE
8404     memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
8405         session->GetCallingUid(), isVisible));
8406 #endif
8407         CheckAndNotifyWaterMarkChangedResult();
8408     }
8409     if (windowVisibilityInfos.size() != 0) {
8410         WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
8411             visibilityInfo.c_str());
8412         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8413     }
8414 #ifdef MEMMGR_WINDOW_ENABLE
8415     if (memMgrWindowInfos.size() != 0) {
8416         WLOGD("Notify memMgrWindowInfos changed start");
8417         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8418     }
8419 #endif
8420 }
8421 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)8422 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
8423     drawingContentChangeInfo)
8424 {
8425     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
8426     for (const auto& elem : drawingContentChangeInfo) {
8427         uint64_t surfaceId = elem.first;
8428         bool drawingState = elem.second;
8429         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8430         if (session == nullptr) {
8431             continue;
8432         }
8433         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
8434             session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
8435         if (openDebugTrace) {
8436             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
8437                 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
8438         }
8439         WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
8440             "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
8441     }
8442     if (windowDrawingContenInfos.size() != 0) {
8443         WLOGFD("Notify WindowDrawingContenInfo changed start");
8444         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
8445     }
8446 }
8447 
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)8448 WSError SceneSessionManager::NotifyAppUseControlList(
8449     ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
8450 {
8451     TLOGI(WmsLogTag::WMS_LIFE,
8452         "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
8453         static_cast<int>(type), userId, controlList.size());
8454     if (!SessionPermission::IsSACalling()) {
8455         TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8456         return WSError::WS_ERROR_INVALID_PERMISSION;
8457     }
8458     if (type == ControlAppType::APP_LOCK &&
8459         !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
8460         TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
8461         return WSError::WS_ERROR_INVALID_PERMISSION;
8462     }
8463     if (currentUserId_ != userId) {
8464         if (currentUserId_ != DEFAULT_USERID) {
8465             TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
8466                 currentUserId_.load(), userId);
8467             return WSError::WS_ERROR_INVALID_OPERATION;
8468         }
8469         int32_t userIdByUid = GetUserIdByUid(getuid());
8470         if (userId != userIdByUid) {
8471             TLOGW(WmsLogTag::WMS_LIFE,
8472                 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
8473                 currentUserId_.load(), userId, userIdByUid);
8474             return WSError::WS_ERROR_INVALID_OPERATION;
8475         }
8476     }
8477     taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
8478         if (notifyAppUseControlListFunc_ != nullptr) {
8479             notifyAppUseControlListFunc_(type, userId, controlList);
8480         }
8481 
8482         std::vector<sptr<SceneSession>> mainSessions;
8483         for (const auto& appUseControlInfo : controlList) {
8484             GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
8485             if (mainSessions.empty()) {
8486                 continue;
8487             }
8488             for (const auto& session : mainSessions) {
8489                 session->NotifyUpdateAppUseControl(type, appUseControlInfo.isNeedControl_);
8490             }
8491             mainSessions.clear();
8492         }
8493     }, __func__);
8494     return WSError::WS_OK;
8495 }
8496 
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)8497 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
8498 {
8499     taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
8500         notifyAppUseControlListFunc_ = std::move(callback);
8501     }, __func__);
8502 }
8503 
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)8504 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
8505     std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
8506 {
8507     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
8508     for (const auto& data : currDrawingContentData) {
8509         uint64_t windowId = data.first;
8510         bool currentDrawingContentState = data.second;
8511         int32_t pid = 0;
8512         bool isChange = false;
8513         if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
8514             continue;
8515         } else {
8516             isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
8517         }
8518         if (isChange) {
8519             processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
8520         }
8521     }
8522     return processDrawingContentChangeInfo;
8523 }
8524 
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)8525 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
8526 {
8527     bool preWindowDrawingState = true;
8528     sptr<SceneSession> session = SelectSesssionFromMap(windowId);
8529     if (session == nullptr) {
8530         return false;
8531     }
8532     pid = session->GetCallingPid();
8533     preWindowDrawingState = session->GetDrawingContentState();
8534     session->SetDrawingContentState(currentDrawingContentState);
8535     return preWindowDrawingState;
8536 }
8537 
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)8538 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
8539 {
8540     bool isChange = true;
8541     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8542     for (const auto& item : sceneSessionMap_) {
8543         auto sceneSession = item.second;
8544         if (sceneSession == nullptr) {
8545             continue;
8546         }
8547         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
8548             windowId != sceneSession->GetSurfaceNode()->GetId()) {
8549             if (sceneSession->GetDrawingContentState()) {
8550                 return false;
8551             }
8552         }
8553     }
8554     return isChange;
8555 }
8556 
InitWithRenderServiceAdded()8557 void SceneSessionManager::InitWithRenderServiceAdded()
8558 {
8559     auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
8560         this->WindowLayerInfoChangeCallback(occlusiontionData);
8561     };
8562     WLOGI("RegisterWindowVisibilityChangeCallback");
8563     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
8564         WLOGFE("RegisterWindowVisibilityChangeCallback failed");
8565     }
8566 }
8567 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)8568 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
8569 {
8570     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
8571         WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
8572         return WMError::WM_ERROR_INVALID_PARAM;
8573     }
8574 
8575     auto task = [this, sceneType]() {
8576         WLOGFD("Set system animated scene %{public}d.", sceneType);
8577         bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
8578         if (!ret) {
8579             WLOGFE("Set system animated scene failed.");
8580         }
8581     };
8582     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
8583     return WMError::WM_OK;
8584 }
8585 
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)8586 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
8587 {
8588     if (!SessionPermission::IsSystemCalling()) {
8589         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
8590         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8591     }
8592     if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
8593         TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
8594         return WSError::WS_ERROR_INVALID_PERMISSION;
8595     }
8596     TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
8597         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
8598     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8599     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
8600         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
8601 	WindowType::WINDOW_TYPE_APP_COMPONENT));
8602     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8603     return WSError::WS_OK;
8604 }
8605 
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)8606 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
8607 {
8608     if (sceneSession == nullptr) {
8609         WLOGFE("sceneSession is nullptr!");
8610         return;
8611     }
8612     if (sceneSession->GetRSVisible()) {
8613         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8614 #ifdef MEMMGR_WINDOW_ENABLE
8615         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
8616 #endif
8617         sceneSession->SetRSVisible(false);
8618         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8619         sceneSession->ClearExtWindowFlags();
8620         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
8621             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
8622             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
8623 #ifdef MEMMGR_WINDOW_ENABLE
8624         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
8625             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
8626 #endif
8627         WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
8628             sceneSession->GetWindowId(), sceneSession->GetRSVisible());
8629         CheckAndNotifyWaterMarkChangedResult();
8630         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8631 #ifdef MEMMGR_WINDOW_ENABLE
8632         WLOGD("Notify memMgrWindowInfos changed start");
8633         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8634 #endif
8635     }
8636 }
8637 
FindSessionByToken(const sptr<IRemoteObject> & token)8638 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
8639 {
8640     if (token == nullptr) {
8641         TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
8642         return nullptr;
8643     }
8644     sptr<SceneSession> session = nullptr;
8645     auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8646         if (pair.second == nullptr) {
8647             return false;
8648         }
8649         return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
8650     };
8651     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8652     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8653     if (iter != sceneSessionMap_.end()) {
8654         session = iter->second;
8655     }
8656     return session;
8657 }
8658 
FindSessionByAffinity(std::string affinity)8659 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
8660 {
8661     if (affinity.size() == 0) {
8662         WLOGFI("AbilityInfo affinity is empty");
8663         return nullptr;
8664     }
8665     sptr<SceneSession> session = nullptr;
8666     auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8667         if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
8668             return false;
8669         }
8670         return pair.second->GetSessionInfo().sessionAffinity == affinity;
8671     };
8672     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8673     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8674     if (iter != sceneSessionMap_.end()) {
8675         session = iter->second;
8676     }
8677     return session;
8678 }
8679 
PreloadInLakeApp(const std::string & bundleName)8680 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
8681 {
8682     WLOGFD("Enter name %{public}s", bundleName.c_str());
8683     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
8684     if (collaborator != nullptr) {
8685         WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
8686         collaborator->NotifyPreloadAbility(bundleName);
8687     }
8688 }
8689 
PendingSessionToForeground(const sptr<IRemoteObject> & token)8690 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
8691 {
8692     TLOGI(WmsLogTag::DEFAULT, "Session is going to foreground");
8693     auto pid = IPCSkeleton::GetCallingRealPid();
8694     if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
8695         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
8696         return WSError::WS_ERROR_INVALID_PERMISSION;
8697     }
8698 
8699     auto task = [this, &token]() {
8700         auto session = FindSessionByToken(token);
8701         if (session != nullptr) {
8702             return session->PendingSessionToForeground();
8703         }
8704         TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
8705         return WSError::WS_ERROR_INVALID_PARAM;
8706     };
8707     return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
8708 }
8709 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)8710 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
8711     bool shouldBackToCaller)
8712 {
8713     auto task = [this, &token, shouldBackToCaller] {
8714         auto session = FindSessionByToken(token);
8715         if (session != nullptr) {
8716             return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
8717         }
8718         TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
8719         return WSError::WS_ERROR_INVALID_PARAM;
8720     };
8721     return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
8722 }
8723 
ClearDisplayStatusBarTemporarilyFlags()8724 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
8725 {
8726     for (auto persistentId : avoidAreaListenerSessionSet_) {
8727         auto sceneSession = GetSceneSession(persistentId);
8728         if (sceneSession == nullptr) {
8729             continue;
8730         }
8731         sceneSession->SetIsDisplayStatusBarTemporarily(false);
8732     }
8733 }
8734 
GetFocusSessionToken(sptr<IRemoteObject> & token)8735 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
8736 {
8737     if (!SessionPermission::IsSACalling()) {
8738         WLOGFE("GetFocusSessionToken permission denied!");
8739         return WSError::WS_ERROR_INVALID_PERMISSION;
8740     }
8741     auto task = [this, &token]() {
8742         WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
8743         auto sceneSession = GetSceneSession(focusedSessionId_);
8744         if (sceneSession) {
8745             token = sceneSession->GetAbilityToken();
8746             if (token == nullptr) {
8747                 WLOGFE("token is nullptr");
8748                 return WSError::WS_ERROR_INVALID_PARAM;
8749             }
8750             return WSError::WS_OK;
8751         }
8752         return WSError::WS_ERROR_INVALID_PARAM;
8753     };
8754     return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
8755 }
8756 
GetFocusSessionElement(AppExecFwk::ElementName & element)8757 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
8758 {
8759     AppExecFwk::RunningProcessInfo info;
8760     auto pid = IPCSkeleton::GetCallingRealPid();
8761     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
8762     if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
8763         WLOGFE("GetFocusSessionElement permission denied!");
8764         return WSError::WS_ERROR_INVALID_PERMISSION;
8765     }
8766     auto task = [this, &element]() {
8767         WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
8768         auto sceneSession = GetSceneSession(focusedSessionId_);
8769         if (sceneSession) {
8770             auto sessionInfo = sceneSession->GetSessionInfo();
8771             element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
8772                 sessionInfo.abilityName_, sessionInfo.moduleName_);
8773             return WSError::WS_OK;
8774         }
8775         return WSError::WS_ERROR_INVALID_SESSION;
8776     };
8777     return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
8778 }
8779 
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)8780 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
8781 {
8782     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8783     auto task = [this, persistentId, haveListener, callingPid]() {
8784         TLOGI(WmsLogTag::WMS_IMMS,
8785             "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
8786             persistentId, haveListener);
8787         auto sceneSession = GetSceneSession(persistentId);
8788         if (sceneSession == nullptr) {
8789             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8790             return WSError::WS_DO_NOTHING;
8791         }
8792         if (callingPid != sceneSession->GetCallingPid()) {
8793             TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
8794             return WSError::WS_ERROR_INVALID_PERMISSION;
8795         }
8796         if (haveListener) {
8797             avoidAreaListenerSessionSet_.insert(persistentId);
8798             UpdateAvoidArea(persistentId);
8799         } else {
8800             avoidAreaListenerSessionSet_.erase(persistentId);
8801         }
8802         return WSError::WS_OK;
8803     };
8804     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
8805 }
8806 
UpdateAvoidSessionAvoidArea(WindowType type)8807 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type)
8808 {
8809     bool ret = true;
8810     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
8811         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
8812     for (auto& persistentId : avoidAreaListenerSessionSet_) {
8813         auto sceneSession = GetSceneSession(persistentId);
8814         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8815             continue;
8816         }
8817         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(avoidType);
8818         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidType);
8819     }
8820 }
8821 
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)8822 void SceneSessionManager::UpdateNormalSessionAvoidArea(
8823     const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
8824 {
8825     bool ret = true;
8826     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8827         TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
8828             persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
8829         needUpdate = false;
8830         return;
8831     }
8832     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8833         TLOGD(WmsLogTag::WMS_IMMS,
8834             "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
8835         needUpdate = false;
8836         return;
8837     }
8838     sceneSession->UpdateSizeChangeReason(SizeChangeReason::AVOID_AREA_CHANGE);
8839     sceneSession->NotifyClientToUpdateRect("AvoidAreaChange", nullptr);
8840 }
8841 
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)8842 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
8843 {
8844     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
8845     auto sceneSession = GetSceneSession(windowId);
8846     if (sceneSession == nullptr) {
8847         WLOGFW("window not exist: %{public}d", windowId);
8848         return;
8849     }
8850 
8851     wptr<SceneSession> weakSceneSession(sceneSession);
8852     WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
8853     auto task = [weakSceneSession, startMoving]() -> WSError {
8854         auto scnSession = weakSceneSession.promote();
8855         if (scnSession == nullptr) {
8856             WLOGFW("session is null");
8857             return WSError::WS_ERROR_NULLPTR;
8858         }
8859         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8860         return WSError::WS_OK;
8861     };
8862     return taskScheduler_->PostAsyncTask(task);
8863 }
8864 
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)8865 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
8866     const std::string taskName, const int delayTime)
8867 {
8868     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
8869 }
8870 
UpdateAvoidArea(int32_t persistentId)8871 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8872 {
8873     auto task = [this, persistentId] {
8874         bool needUpdate = false;
8875         auto sceneSession = GetSceneSession(persistentId);
8876         if (sceneSession == nullptr) {
8877             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8878             return;
8879         }
8880         WindowType type = sceneSession->GetWindowType();
8881         if (sceneSession->IsImmersiveType()) {
8882             UpdateAvoidSessionAvoidArea(type);
8883         } else {
8884             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8885         }
8886         if (needUpdate) {
8887             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8888         }
8889         return;
8890     };
8891     taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8892     return;
8893 }
8894 
UpdateGestureBackEnabled(int32_t persistentId)8895 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8896 {
8897     auto task = [this, persistentId] {
8898         auto sceneSession = GetSceneSession(persistentId);
8899         if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8900             TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8901             return;
8902         }
8903         auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8904         if (needEnableGestureBack) {
8905             gestureBackEnableWindowIdSet_.erase(persistentId);
8906         } else {
8907             gestureBackEnableWindowIdSet_.insert(persistentId);
8908         }
8909         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8910             sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8911             (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8912              sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8913             enterRecent_.load() || !sceneSession->IsFocused()) {
8914             needEnableGestureBack = true;
8915         }
8916         if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8917             gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8918                 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8919         } else {
8920             TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8921         }
8922     };
8923     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8924 }
8925 
UpdateOccupiedAreaIfNeed(const int32_t & persistentId)8926 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8927 {
8928     auto task = [this, persistentId]() {
8929         sptr<SceneSession> keyboardSession = nullptr;
8930         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8931         for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8932             auto sceneSession = item->second;
8933             if (sceneSession != nullptr &&
8934                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8935                 keyboardSession = sceneSession;
8936                 break;
8937             }
8938         }
8939         if (keyboardSession == nullptr) {
8940             TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8941             return;
8942         }
8943         if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8944             return;
8945         }
8946 
8947         keyboardSession->OnCallingSessionUpdated();
8948         return;
8949     };
8950     taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8951     return;
8952 }
8953 
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)8954 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8955 {
8956     TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8957         isVisible, persistentId);
8958     auto task = [this, persistentId, isVisible] {
8959         auto sceneSession = GetSceneSession(persistentId);
8960         if (sceneSession == nullptr) {
8961             TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8962             return;
8963         }
8964         sceneSession->SetIsStatusBarVisible(isVisible);
8965     };
8966     taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8967     return WSError::WS_OK;
8968 }
8969 
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)8970 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8971 {
8972     WLOGFI("isVisible: %{public}u, "
8973         "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8974         isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8975     auto task = [this, isVisible, barArea, displayId]() {
8976         bool isNeedUpdate = true;
8977         {
8978             std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8979             isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8980                 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8981                 currAINavigationBarAreaMap_[displayId] != barArea;
8982             if (isNeedUpdate) {
8983                 isAINavigationBarVisible_ = isVisible;
8984                 currAINavigationBarAreaMap_.clear();
8985                 currAINavigationBarAreaMap_[displayId] = barArea;
8986             }
8987             if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8988                 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8989                 currAINavigationBarAreaMap_[displayId] = WSRect();
8990             }
8991         }
8992         if (isNeedUpdate) {
8993             WLOGFI("NotifyAINavigationBar inner: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8994                 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8995             for (auto persistentId : avoidAreaListenerSessionSet_) {
8996                 NotifySessionAINavigationBarChange(persistentId);
8997             }
8998         }
8999     };
9000     taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
9001     return WSError::WS_OK;
9002 }
9003 
NotifySessionAINavigationBarChange(int32_t persistentId)9004 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
9005 {
9006     auto sceneSession = GetSceneSession(persistentId);
9007     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
9008         return;
9009     }
9010     bool isLastFrameLayoutFinished = true;
9011     IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
9012     TLOGI(WmsLogTag::WMS_IMMS, "window [%{public}d] is layout finished: %{public}d",
9013         persistentId, isLastFrameLayoutFinished);
9014     if (isLastFrameLayoutFinished) {
9015         sceneSession->UpdateAvoidArea(
9016             new AvoidArea(sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR)),
9017             AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
9018     } else {
9019         sceneSession->MarkAvoidAreaAsDirty();
9020     }
9021 }
9022 
GetAINavigationBarArea(uint64_t displayId)9023 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
9024 {
9025     std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
9026     if (currAINavigationBarAreaMap_.count(displayId) == 0) {
9027         return {};
9028     }
9029     return currAINavigationBarAreaMap_[displayId];
9030 }
9031 
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)9032 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
9033 {
9034     const auto callingPid = IPCSkeleton::GetCallingRealPid();
9035     auto task = [this, persistentId, haveListener, callingPid]() {
9036         TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
9037             persistentId, haveListener);
9038         auto sceneSession = GetSceneSession(persistentId);
9039         if (sceneSession == nullptr) {
9040             TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
9041             return WSError::WS_DO_NOTHING;
9042         }
9043         if (callingPid != sceneSession->GetCallingPid()) {
9044             TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
9045             return WSError::WS_ERROR_INVALID_PERMISSION;
9046         }
9047         if (haveListener) {
9048             touchOutsideListenerSessionSet_.insert(persistentId);
9049         } else {
9050             touchOutsideListenerSessionSet_.erase(persistentId);
9051         }
9052         return WSError::WS_OK;
9053     };
9054     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
9055 }
9056 
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)9057 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
9058 {
9059     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
9060     auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
9061         WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
9062             persistentId, haveListener);
9063         auto sceneSession = GetSceneSession(persistentId);
9064         if (sceneSession == nullptr) {
9065             WLOGFD("sceneSession is nullptr.");
9066             return WSError::WS_DO_NOTHING;
9067         }
9068         if (callingPid != sceneSession->GetCallingPid()) {
9069             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
9070             return WSError::WS_ERROR_INVALID_PERMISSION;
9071         }
9072         if (haveListener) {
9073             windowVisibilityListenerSessionSet_.insert(persistentId);
9074             sceneSession->NotifyWindowVisibility();
9075         } else {
9076             windowVisibilityListenerSessionSet_.erase(persistentId);
9077         }
9078         return WSError::WS_OK;
9079     };
9080     return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
9081 }
9082 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)9083 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
9084 {
9085     processVirtualPixelRatioChangeFunc_ = func;
9086     WLOGFI("SetVirtualPixelRatioChangeListener");
9087 }
9088 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)9089 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
9090     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
9091 {
9092     if (displayInfo == nullptr) {
9093         WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
9094         return;
9095     }
9096     auto task = [this, displayInfo]() {
9097         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9098         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
9099             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
9100             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
9101                 displayInfo->GetWidth(), displayInfo->GetHeight()
9102             };
9103             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
9104         }
9105         for (const auto &item : sceneSessionMap_) {
9106             auto scnSession = item.second;
9107             if (scnSession == nullptr) {
9108                 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
9109                 continue;
9110             }
9111             SessionInfo sessionInfo = scnSession->GetSessionInfo();
9112             if (sessionInfo.isSystem_) {
9113                 continue;
9114             }
9115             if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
9116                 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
9117                 scnSession->UpdateDensity();
9118                 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
9119                     "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
9120                     scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
9121             }
9122         }
9123         UpdateDisplayRegion(displayInfo);
9124         return WSError::WS_OK;
9125     };
9126     taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
9127 }
9128 
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)9129 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
9130     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
9131 {
9132     if (displayInfo == nullptr) {
9133         WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
9134         return;
9135     }
9136     auto task = [this, displayInfo]() {
9137         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9138         for (const auto &item : sceneSessionMap_) {
9139             auto scnSession = item.second;
9140             if (scnSession == nullptr) {
9141                 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
9142                 continue;
9143             }
9144             if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
9145                 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
9146                 continue;
9147             }
9148             if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
9149                 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
9150                 scnSession->GetRotation() != displayInfo->GetRotation()) {
9151                 scnSession->UpdateRotationAvoidArea();
9152                 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
9153                     "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
9154                     item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
9155             }
9156             scnSession->SetRotation(displayInfo->GetRotation());
9157             scnSession->UpdateOrientation();
9158         }
9159         UpdateDisplayRegion(displayInfo);
9160         return WSError::WS_OK;
9161     };
9162     taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
9163 }
9164 
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)9165 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
9166 {
9167     if (displayInfo == nullptr) {
9168         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
9169         return;
9170     }
9171 
9172     auto task = [displayInfo]() -> WSError {
9173         ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
9174             displayInfo->GetScaleX(),
9175             displayInfo->GetScaleY(),
9176             displayInfo->GetPivotX(),
9177             displayInfo->GetPivotY(),
9178             displayInfo->GetTranslateX(),
9179             displayInfo->GetTranslateY());
9180         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
9181         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
9182         return WSError::WS_OK;
9183     };
9184     return taskScheduler_->PostAsyncTask(task);
9185 }
9186 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)9187 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
9188     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
9189 {
9190     WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
9191     switch (type) {
9192         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
9193             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
9194                 displayInfo, displayInfoMap, type);
9195             break;
9196         }
9197         case DisplayStateChangeType::UPDATE_ROTATION: {
9198             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
9199                 displayInfo, displayInfoMap, type);
9200             break;
9201         }
9202         case DisplayStateChangeType::UPDATE_SCALE: {
9203             SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
9204             break;
9205         }
9206         default:
9207             return;
9208     }
9209 }
9210 
OnScreenshot(DisplayId displayId)9211 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
9212 {
9213     SceneSessionManager::GetInstance().OnScreenshot(displayId);
9214 }
9215 
OnScreenshot(DisplayId displayId)9216 void SceneSessionManager::OnScreenshot(DisplayId displayId)
9217 {
9218     auto task = [this, displayId]() {
9219         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9220         for (const auto& iter : sceneSessionMap_) {
9221             auto sceneSession = iter.second;
9222             if (sceneSession == nullptr) {
9223                 continue;
9224             }
9225             auto state = sceneSession->GetSessionState();
9226             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
9227                 sceneSession->NotifyScreenshot();
9228             }
9229         }
9230     };
9231     taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
9232 }
9233 
ClearSession(int32_t persistentId)9234 WSError SceneSessionManager::ClearSession(int32_t persistentId)
9235 {
9236     WLOGFI("id: %{public}d", persistentId);
9237     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9238         WLOGFE("The caller is not system-app, can not use system-api");
9239         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9240     }
9241     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9242         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9243         return WSError::WS_ERROR_INVALID_PERMISSION;
9244     }
9245     auto task = [this, persistentId]() {
9246         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
9247         return ClearSession(sceneSession);
9248     };
9249     taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
9250     return WSError::WS_OK;
9251 }
9252 
ClearSession(sptr<SceneSession> sceneSession)9253 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
9254 {
9255     WLOGFD("Enter");
9256     if (sceneSession == nullptr) {
9257         WLOGFE("session is nullptr");
9258         return WSError::WS_ERROR_INVALID_SESSION;
9259     }
9260     if (!IsSessionClearable(sceneSession)) {
9261         WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
9262         return WSError::WS_ERROR_INVALID_SESSION;
9263     }
9264     const WSError errCode = sceneSession->Clear();
9265     return errCode;
9266 }
9267 
ClearAllSessions()9268 WSError SceneSessionManager::ClearAllSessions()
9269 {
9270     WLOGFD("Enter");
9271     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9272         WLOGFE("The caller is not system-app, can not use system-api");
9273         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9274     }
9275     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9276         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9277         return WSError::WS_ERROR_INVALID_PERMISSION;
9278     }
9279     auto task = [this]() {
9280         std::vector<sptr<SceneSession>> sessionVector;
9281         GetAllClearableSessions(sessionVector);
9282         for (uint32_t i = 0; i < sessionVector.size(); i++) {
9283             ClearSession(sessionVector[i]);
9284         }
9285         return WSError::WS_OK;
9286     };
9287     taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
9288     return WSError::WS_OK;
9289 }
9290 
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)9291 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
9292 {
9293     WLOGFD("Enter");
9294     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9295     for (const auto &item : sceneSessionMap_) {
9296         auto scnSession = item.second;
9297         if (IsSessionClearable(scnSession)) {
9298             sessionVector.push_back(scnSession);
9299         }
9300     }
9301 }
9302 
LockSession(int32_t sessionId)9303 WSError SceneSessionManager::LockSession(int32_t sessionId)
9304 {
9305     WLOGFI("id: %{public}d", sessionId);
9306     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9307         WLOGFE("The caller is not system-app, can not use system-api");
9308         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9309     }
9310     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9311         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9312         return WSError::WS_ERROR_INVALID_PERMISSION;
9313     }
9314     auto task = [this, sessionId]() {
9315         auto sceneSession = GetSceneSession(sessionId);
9316         if (sceneSession == nullptr) {
9317             WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
9318             return WSError::WS_ERROR_INVALID_PARAM;
9319         }
9320         sceneSession->SetSessionInfoLockedState(true);
9321         return WSError::WS_OK;
9322     };
9323     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
9324 }
9325 
UnlockSession(int32_t sessionId)9326 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
9327 {
9328     WLOGFI("id: %{public}d", sessionId);
9329     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9330         WLOGFE("The caller is not system-app, can not use system-api");
9331         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9332     }
9333     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9334         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9335         return WSError::WS_ERROR_INVALID_PERMISSION;
9336     }
9337     auto task = [this, sessionId]() {
9338         auto sceneSession = GetSceneSession(sessionId);
9339         if (sceneSession == nullptr) {
9340             WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
9341             return WSError::WS_ERROR_INVALID_PARAM;
9342         }
9343         sceneSession->SetSessionInfoLockedState(false);
9344         return WSError::WS_OK;
9345     };
9346     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
9347 }
9348 
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)9349 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
9350 {
9351     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9352     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9353         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9354         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9355     }
9356     if (!SessionPermission::VerifySessionPermission()) {
9357         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9358         return WSError::WS_ERROR_INVALID_PERMISSION;
9359     }
9360 
9361     return WSError::WS_OK;
9362 }
9363 
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)9364 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
9365     std::vector<int32_t>& result)
9366 {
9367     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9368     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9369         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9370         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9371     }
9372     if (!SessionPermission::VerifySessionPermission()) {
9373         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9374         return WSError::WS_ERROR_INVALID_PERMISSION;
9375     }
9376 
9377     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
9378     return WSError::WS_OK;
9379 }
9380 
IsSessionClearable(sptr<SceneSession> scnSession)9381 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
9382 {
9383     if (scnSession == nullptr) {
9384         WLOGFI("scnSession is nullptr");
9385         return false;
9386     }
9387     SessionInfo sessionInfo = scnSession->GetSessionInfo();
9388     if (sessionInfo.abilityInfo == nullptr) {
9389         WLOGFI("scnSession abilityInfo is nullptr");
9390         return false;
9391     }
9392     if (sessionInfo.abilityInfo->excludeFromMissions && !scnSession->IsAnco()) {
9393         WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
9394         return false;
9395     }
9396     if (sessionInfo.abilityInfo->unclearableMission) {
9397         WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
9398         return false;
9399     }
9400     if (sessionInfo.isSystem_) {
9401         WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
9402         return false;
9403     }
9404     if (sessionInfo.lockedState) {
9405         WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
9406         return false;
9407     }
9408 
9409     return true;
9410 }
9411 
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)9412 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
9413     const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
9414 {
9415     WLOGFI("type: %{public}d", type);
9416     auto isSaCall = SessionPermission::IsSACalling();
9417     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9418         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9419         return WSError::WS_ERROR_INVALID_PERMISSION;
9420     }
9421     if (!CheckCollaboratorType(type)) {
9422         WLOGFW("collaborator register failed, invalid type.");
9423         return WSError::WS_ERROR_INVALID_TYPE;
9424     }
9425     {
9426         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9427         collaboratorMap_[type] = impl;
9428     }
9429     auto task = [this] {
9430         if (abilityManagerCollaboratorRegisteredFunc_) {
9431             abilityManagerCollaboratorRegisteredFunc_();
9432         }
9433     };
9434     taskScheduler_->PostTask(task, __func__);
9435     return WSError::WS_OK;
9436 }
9437 
UnregisterIAbilityManagerCollaborator(int32_t type)9438 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
9439 {
9440     WLOGFI("type: %{public}d", type);
9441     auto isSaCall = SessionPermission::IsSACalling();
9442     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9443         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9444         return WSError::WS_ERROR_INVALID_PERMISSION;
9445     }
9446     if (!CheckCollaboratorType(type)) {
9447         WLOGFE("collaborator unregister failed, invalid type.");
9448         return WSError::WS_ERROR_INVALID_TYPE;
9449     }
9450     {
9451         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9452         collaboratorMap_.erase(type);
9453     }
9454     return WSError::WS_OK;
9455 }
9456 
CheckCollaboratorType(int32_t type)9457 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
9458 {
9459     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
9460         WLOGFD("type is invalid");
9461         return false;
9462     }
9463     return true;
9464 }
9465 
CheckIfReuseSession(SessionInfo & sessionInfo)9466 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
9467 {
9468     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
9469         sessionInfo.moduleName_);
9470     if (abilityInfo == nullptr) {
9471         WLOGFE("abilityInfo is nullptr!");
9472         return BrokerStates::BROKER_UNKOWN;
9473     }
9474     sessionInfo.abilityInfo = abilityInfo;
9475     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
9476     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
9477         collaboratorType = CollaboratorType::RESERVE_TYPE;
9478     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
9479         collaboratorType = CollaboratorType::OTHERS_TYPE;
9480     }
9481     if (!CheckCollaboratorType(collaboratorType)) {
9482         WLOGFW("checked not collaborator!");
9483         return BrokerStates::BROKER_UNKOWN;
9484     }
9485     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
9486     sessionInfo.collaboratorType_ = collaboratorType;
9487     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9488     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
9489         WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
9490         sessionInfo.reuse = true;
9491     } else {
9492         sessionInfo.reuse = false;
9493     }
9494     WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
9495         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
9496     return resultValue;
9497 }
9498 
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)9499 BrokerStates SceneSessionManager::NotifyStartAbility(
9500     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
9501 {
9502     WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
9503     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9504     if (collaborator == nullptr) {
9505         return BrokerStates::BROKER_UNKOWN;
9506     }
9507     if (sessionInfo.want == nullptr) {
9508         WLOGFI("sessionInfo.want is nullptr, init");
9509         sessionInfo.want = std::make_shared<AAFwk::Want>();
9510         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
9511             sessionInfo.moduleName_);
9512     }
9513     auto accessTokenIDEx = sessionInfo.callingTokenId_;
9514     if (collaborator != nullptr) {
9515         containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
9516             std::chrono::system_clock::now().time_since_epoch()).count();
9517 
9518         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9519         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
9520             WLOGFI("want affinity exit %{public}s.", affinity.c_str());
9521             return BrokerStates::BROKER_UNKOWN;
9522         }
9523         sessionInfo.want->SetParam("oh_persistentId", persistentId);
9524         int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
9525             currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
9526         WLOGFI("collaborator ret: %{public}d", ret);
9527         if (ret == 0) {
9528             return BrokerStates::BROKER_STARTED;
9529         } else {
9530             return BrokerStates::BROKER_NOT_START;
9531         }
9532     }
9533     return BrokerStates::BROKER_UNKOWN;
9534 }
9535 
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)9536 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
9537 {
9538     if (sceneSession == nullptr) {
9539         WLOGFE("sceneSession is nullptr");
9540         return;
9541     }
9542     if (sessionInfo.want == nullptr) {
9543         WLOGFI("sessionInfo.want is nullptr");
9544         return;
9545     }
9546     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9547     if (collaborator == nullptr) {
9548         return;
9549     }
9550     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9551     if (abilitySessionInfo == nullptr) {
9552         WLOGFE("abilitySessionInfo is nullptr");
9553         return;
9554     }
9555     abilitySessionInfo->want = *(sessionInfo.want);
9556     if (collaborator != nullptr) {
9557         int32_t missionId = abilitySessionInfo->persistentId;
9558         std::string bundleName = sessionInfo.bundleName_;
9559         int64_t timestamp = containerStartAbilityTime_;
9560         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
9561         WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
9562             missionId, bundleName.c_str());
9563         collaborator->NotifyMissionCreated(abilitySessionInfo);
9564     }
9565 }
9566 
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)9567 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
9568     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
9569 {
9570     WLOGFD("type: %{public}d", collaboratorType);
9571     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9572     if (collaborator != nullptr) {
9573         WLOGFI("called NotifyLoadAbility");
9574         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
9575     }
9576 }
9577 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)9578 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
9579 {
9580     WLOGFD("Enter");
9581     if (sceneSession == nullptr) {
9582         WLOGFE("sceneSession is nullptr");
9583         return;
9584     }
9585     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9586     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9587     if (collaborator != nullptr) {
9588         WLOGFI("called UpdateMissionInfo");
9589         collaborator->UpdateMissionInfo(abilitySessionInfo);
9590     }
9591 }
9592 
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)9593 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
9594 {
9595     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9596     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9597     if (collaborator != nullptr) {
9598         WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
9599         collaborator->NotifyMoveMissionToForeground(persistentId);
9600     }
9601 }
9602 
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)9603 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
9604 {
9605     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9606     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9607     if (collaborator != nullptr) {
9608         WLOGFI("called NotifyClearMission %{public}d", persistentId);
9609         collaborator->NotifyClearMission(persistentId);
9610     }
9611 }
9612 
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)9613 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
9614 {
9615     if (sceneSession == nullptr) {
9616         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
9617         return false;
9618     }
9619     std::string sessionAffinity;
9620     TLOGI(WmsLogTag::WMS_LIFE, "call");
9621     if (sceneSession->GetSessionInfo().want != nullptr) {
9622         sessionAffinity = sceneSession->GetSessionInfo().want
9623             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9624     }
9625     if (sessionAffinity.empty()) {
9626         TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
9627         BrokerStates notifyReturn = NotifyStartAbility(
9628             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
9629         if (notifyReturn == BrokerStates::BROKER_NOT_START) {
9630             TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
9631             return false;
9632         }
9633     }
9634     if (sceneSession->GetSessionInfo().want != nullptr) {
9635         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
9636             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
9637         TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
9638             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
9639             sceneSession->GetSessionInfo().sessionAffinity.c_str());
9640     } else {
9641         TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
9642     }
9643     return true;
9644 }
9645 
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)9646 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
9647 {
9648     if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
9649         return false;
9650     }
9651     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
9652     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
9653     return true;
9654 }
9655 
AddWindowDragHotArea(uint32_t type,WSRect & area)9656 void SceneSessionManager::AddWindowDragHotArea(uint32_t type, WSRect& area)
9657 {
9658     WLOGFI("type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
9659         "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
9660     SceneSession::AddOrUpdateWindowDragHotArea(type, area);
9661 }
9662 
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)9663 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
9664 {
9665     auto task = [this, persistentId, isMaximize]() -> WSError {
9666         WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
9667         auto sceneSession = GetSceneSession(persistentId);
9668         if (sceneSession == nullptr) {
9669             WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9670             return WSError::WS_ERROR_INVALID_WINDOW;
9671         }
9672         sceneSession->UpdateMaximizeMode(isMaximize);
9673         return WSError::WS_OK;
9674     };
9675     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
9676     return WSError::WS_OK;
9677 }
9678 
GetIsLayoutFullScreen(bool & isLayoutFullScreen)9679 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
9680 {
9681     auto task = [this, &isLayoutFullScreen]() {
9682         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9683         for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9684             auto sceneSession = item->second;
9685             if (sceneSession == nullptr) {
9686                 WLOGFE("Session is nullptr");
9687                 continue;
9688             }
9689             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9690                 continue;
9691             }
9692             auto state = sceneSession->GetSessionState();
9693             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9694                 continue;
9695             }
9696             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9697                 continue;
9698             }
9699             auto property = sceneSession->GetSessionProperty();
9700             if (property == nullptr) {
9701                 WLOGFE("Property is nullptr");
9702                 continue;
9703             }
9704             isLayoutFullScreen = property->IsLayoutFullScreen();
9705             auto persistentId = sceneSession->GetPersistentId();
9706             if (isLayoutFullScreen) {
9707                 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
9708                 return WSError::WS_OK;
9709             } else {
9710                 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
9711             }
9712         }
9713         WLOGFD("No immersive window");
9714         return WSError::WS_OK;
9715     };
9716 
9717     taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
9718     return WSError::WS_OK;
9719 }
9720 
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)9721 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
9722 {
9723     auto scnSession = GetSceneSession(persistentId);
9724     if (!scnSession) {
9725         WLOGFE("session is nullptr");
9726         return WSError::WS_ERROR_INVALID_WINDOW;
9727     }
9728     auto fromScreenId = scnSession->GetSessionInfo().screenId_;
9729     scnSession->SetScreenId(screenId);
9730     auto sessionProperty = scnSession->GetSessionProperty();
9731     if (!sessionProperty) {
9732         WLOGFE("Property is null, synchronous screenId failed");
9733         return WSError::WS_ERROR_NULLPTR;
9734     }
9735     sessionProperty->SetDisplayId(screenId);
9736     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "wid: %{public}d, move display %{public}" PRIu64 "from %{public}" PRIu64,
9737         scnSession->GetPersistentId(), screenId, fromScreenId);
9738     NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
9739     scnSession->NotifyDisplayMove(fromScreenId, screenId);
9740     scnSession->UpdateDensity();
9741     return WSError::WS_OK;
9742 }
9743 
NotifyStackEmpty(int32_t persistentId)9744 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
9745 {
9746     TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
9747     auto task = [this, persistentId]() {
9748         auto scnSession = GetSceneSession(persistentId);
9749         if (!scnSession) {
9750             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
9751             return WSError::WS_ERROR_INVALID_WINDOW;
9752         }
9753         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
9754         return WSError::WS_OK;
9755     };
9756     taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
9757     return WSError::WS_OK;
9758 }
9759 
OnImmersiveStateChange(bool & immersive)9760 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
9761 {
9762     immersive = SceneSessionManager::GetInstance().GetImmersiveState();
9763 }
9764 
GetImmersiveState()9765 bool SceneSessionManager::GetImmersiveState()
9766 {
9767     return taskScheduler_->PostSyncTask([this, where = __func__] {
9768         bool isPcOrPadFreeMultiWindowMode = false;
9769         IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
9770         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9771         for (const auto& [_, sceneSession] : sceneSessionMap_) {
9772             if (sceneSession == nullptr) {
9773                 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
9774                 continue;
9775             }
9776             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9777                 continue;
9778             }
9779             auto state = sceneSession->GetSessionState();
9780             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9781                 continue;
9782             }
9783             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9784                 continue;
9785             }
9786             if (isPcOrPadFreeMultiWindowMode) {
9787                 if (sceneSession->IsLayoutFullScreen()) {
9788                     return true;
9789                 }
9790                 continue;
9791             }
9792             auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
9793             if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
9794                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
9795                     sceneSession->GetPersistentId());
9796                 return true;
9797             } else {
9798                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
9799                     sceneSession->GetPersistentId());
9800                 break;
9801             }
9802         }
9803         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
9804         return false;
9805     }, __func__);
9806 }
9807 
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)9808 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
9809     bool withAnimation)
9810 {
9811     session->NotifySessionForeground(reason, withAnimation);
9812 }
9813 
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)9814 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
9815     bool withAnimation, bool isFromInnerkits)
9816 {
9817     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
9818 }
9819 
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)9820 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
9821 {
9822     auto sceneSession = GetSceneSession(persistentId);
9823     if (sceneSession == nullptr) {
9824         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9825         return WSError::WS_ERROR_INVALID_WINDOW;
9826     }
9827     return sceneSession->UpdateTitleInTargetPos(isShow, height);
9828 }
9829 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9830 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9831 {
9832     WLOGFI("AppAnrListener OnAppDebugStarted");
9833     if (debugInfos.empty()) {
9834         WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9835         return;
9836     }
9837     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
9838 }
9839 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9840 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9841 {
9842     WLOGFI("AppAnrListener OnAppDebugStoped");
9843     if (debugInfos.empty()) {
9844         WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9845         return;
9846     }
9847     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
9848 }
9849 
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)9850 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9851 {
9852     if (!Session::IsScbCoreEnabled()) {
9853         return;
9854     }
9855     if (onFlushUIParamsFunc_ != nullptr) {
9856         onFlushUIParamsFunc_();
9857     }
9858     auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9859         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9860         TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9861         {
9862             std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9863             nextFlushCompletedCV_.notify_all();
9864         }
9865         std::vector<uint32_t> startingAppZOrderList;
9866         processingFlushUIParams_.store(true);
9867         {
9868             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9869             for (const auto& item : sceneSessionMap_) {
9870                 auto sceneSession = item.second;
9871                 if (sceneSession == nullptr) {
9872                     continue;
9873                 }
9874                 if (sceneSession->GetSessionInfo().screenId_ != SCREEN_ID_INVALID &&
9875                     sceneSession->GetSessionInfo().screenId_ != screenId) {
9876                     continue;
9877                 }
9878                 auto iter = uiParams.find(sceneSession->GetPersistentId());
9879                 if (iter != uiParams.end()) {
9880                     if (sceneSession->GetSessionInfo().screenId_ == SCREEN_ID_INVALID) {
9881                         sceneSession->SetScreenIdOnServer(screenId);
9882                     }
9883                     if ((systemConfig_.uiType_ == UI_TYPE_PHONE ||
9884                          (systemConfig_.uiType_ == UI_TYPE_PAD && !systemConfig_.IsFreeMultiWindowMode())) &&
9885                         sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
9886                         startingAppZOrderList.push_back(iter->second.zOrder_);
9887                         sceneSession->SetStartingBeforeVisible(false);
9888                     }
9889                     sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9890                 } else {
9891                     sessionMapDirty_ |= sceneSession->UpdateUIParam();
9892                 }
9893             }
9894         }
9895         processingFlushUIParams_.store(false);
9896 
9897         // post process if dirty
9898         if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9899             static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9900             TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9901             for (const auto& item : uiParams) {
9902                 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f"
9903                     " transY:%{public}f, needSync:%{public}d, intreactive:%{public}d", item.first, item.second.zOrder_,
9904                     item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
9905                     item.second.needSync_, item.second.interactive_);
9906             }
9907             ProcessUpdateLastFocusedAppId(startingAppZOrderList);
9908             ProcessFocusZOrderChange(sessionMapDirty_);
9909             PostProcessFocus();
9910             PostProcessProperty(sessionMapDirty_);
9911             NotifyAllAccessibilityInfo();
9912             AnomalyDetection::SceneZOrderCheckProcess();
9913         } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9914             PostProcessProperty(sessionMapDirty_);
9915         }
9916         FlushWindowInfoToMMI();
9917         sessionMapDirty_ = 0;
9918         {
9919             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9920             for (const auto& item : sceneSessionMap_) {
9921                 auto sceneSession = item.second;
9922                 if (sceneSession == nullptr) {
9923                     continue;
9924                 }
9925                 sceneSession->ResetSizeChangeReasonIfDirty();
9926                 sceneSession->ResetDirtyFlags();
9927                 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9928                     sceneSession->SetUIStateDirty(false);
9929                 }
9930             }
9931         }
9932     };
9933     taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9934 }
9935 
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)9936 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
9937 {
9938     TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu", lastFocusedAppSessionId_,
9939           zOrderList.size());
9940     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || zOrderList.empty()) {
9941         return;
9942     }
9943     auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId_);
9944     if (lastFocusedAppSession == nullptr) {
9945         return;
9946     }
9947     uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
9948     auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
9949         return zOrder > lastFocusedAppZOrder;
9950     });
9951     if (it != zOrderList.end()) {
9952         TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
9953         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
9954     }
9955 }
9956 
ProcessFocusZOrderChange(uint32_t dirty)9957 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
9958 {
9959     if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9960         return;
9961     }
9962     if (systemConfig_.uiType_ != UI_TYPE_PHONE && systemConfig_.uiType_ != UI_TYPE_PAD) {
9963         return;
9964     }
9965     TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9966     auto focusedSession = GetSceneSession(focusedSessionId_);
9967     // only when it's from a high zOrder to a low zOrder
9968     if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9969         focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9970         return;
9971     }
9972     auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9973     if (voiceInteractionSession == nullptr) {
9974         return;
9975     }
9976     TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9977           "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9978           voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9979     if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9980         focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9981         return;
9982     }
9983     RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9984 }
9985 
PostProcessFocus()9986 void SceneSessionManager::PostProcessFocus()
9987 {
9988     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9989     // priority process focus requests from top to bottom
9990     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9991     {
9992         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9993         for (auto& iter : sceneSessionMap_) {
9994             auto session = iter.second;
9995             if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9996                 continue;
9997             }
9998             processingSessions.push_back(iter);
9999         }
10000     }
10001     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
10002         bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
10003             !rhs.second->GetPostProcessFocusState().isFocused_;
10004         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
10005         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
10006         return focusCmp || lhsZOrder > rhsZOrder;
10007     };
10008     std::sort(processingSessions.begin(), processingSessions.end(), cmp);
10009 
10010     // only change focus one time
10011     bool focusChanged = false;
10012     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
10013         auto session = iter->second;
10014         if (session == nullptr) {
10015             WLOGFE("session is nullptr");
10016             continue;
10017         }
10018         TLOGD(WmsLogTag::WMS_PIPELINE,
10019             "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
10020             session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
10021             session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
10022         if (focusChanged) {
10023             session->ResetPostProcessFocusState();
10024             continue;
10025         }
10026         WSError ret = WSError::WS_DO_NOTHING;
10027         if (session->GetPostProcessFocusState().isFocused_) {
10028             if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
10029                 ret = RequestSessionFocusImmediately(session->GetPersistentId());
10030             } else {
10031                 ret = RequestSessionFocus(session->GetPersistentId(), true,
10032                                           session->GetPostProcessFocusState().reason_);
10033             }
10034         } else {
10035             ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
10036         }
10037         session->ResetPostProcessFocusState();
10038         // if succeed then end process
10039         if (ret == WSError::WS_OK) {
10040             focusChanged = true;
10041         }
10042     }
10043 }
10044 
PostProcessProperty(uint32_t dirty)10045 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
10046 {
10047     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
10048     if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
10049         // only trigger update avoid area
10050         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10051         for (auto& iter : sceneSessionMap_) {
10052             auto session = iter.second;
10053             if (session == nullptr) {
10054                 continue;
10055             }
10056             session->PostProcessNotifyAvoidArea();
10057         }
10058         return;
10059     }
10060 
10061     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
10062     {
10063         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10064         for (auto& iter : sceneSessionMap_) {
10065             auto session = iter.second;
10066             if (session == nullptr || !session->GetPostProcessProperty()) {
10067                 continue;
10068             }
10069             processingSessions.push_back(iter);
10070         }
10071     }
10072 
10073     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
10074         auto session = iter->second;
10075         if (session == nullptr) {
10076             WLOGFE("session is nullptr");
10077             continue;
10078         }
10079         TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
10080         UpdateForceHideState(session, session->GetSessionProperty(), true);
10081         HandleKeepScreenOn(session, session->IsKeepScreenOn());
10082         UpdatePrivateStateAndNotify(session->GetPersistentId());
10083         if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10084             ProcessSubSessionForeground(session);
10085         }
10086         session->SetPostProcessProperty(false);
10087     }
10088 
10089     // update avoid area
10090     {
10091         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10092         for (auto& iter : sceneSessionMap_) {
10093             auto session = iter.second;
10094             if (session == nullptr) {
10095                 continue;
10096             }
10097             session->PostProcessNotifyAvoidArea();
10098         }
10099     }
10100 }
10101 
10102 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)10103 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
10104 {
10105     WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
10106     auto isSaCall = SessionPermission::IsSACalling();
10107     if (!isSaCall) {
10108         WLOGFE("The interface only support for sa call");
10109         return WSError::WS_ERROR_INVALID_PERMISSION;
10110     }
10111     auto task = [this, persistentId]() {
10112         auto sceneSession = GetSceneSession(persistentId);
10113         if (sceneSession == nullptr) {
10114             WLOGFE("session is nullptr");
10115             return WSError::WS_ERROR_INVALID_SESSION;
10116         }
10117         if (!IsSessionVisibleForeground(sceneSession)) {
10118             WLOGFD("session is not visible!");
10119             return WSError::WS_DO_NOTHING;
10120         }
10121         FocusChangeReason reason = FocusChangeReason::MOVE_UP;
10122         RequestSessionFocus(persistentId, true, reason);
10123         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
10124             sceneSession->RaiseToAppTop();
10125         }
10126         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
10127             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
10128             WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
10129             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
10130         }
10131         if (sceneSession == nullptr) {
10132             WLOGFE("parent session is nullptr");
10133             return WSError::WS_ERROR_INVALID_SESSION;
10134         }
10135         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10136             sceneSession->NotifyClick();
10137             return WSError::WS_OK;
10138         } else {
10139             WLOGFE("session is not app main window!");
10140             return WSError::WS_ERROR_INVALID_SESSION;
10141         }
10142     };
10143     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
10144     return WSError::WS_OK;
10145 }
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)10146 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
10147 {
10148     WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
10149     if (sourcePersistentId != focusedSessionId_) {
10150         WLOGFE("source session need be focused");
10151         return WSError::WS_ERROR_INVALID_OPERATION;
10152     }
10153     if (targetPersistentId == focusedSessionId_) {
10154         WLOGFE("target session has been focused");
10155         return WSError::WS_DO_NOTHING;
10156     }
10157     sptr<SceneSession> sourceSession = nullptr;
10158     WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
10159     if (ret != WSError::WS_OK) {
10160         return ret;
10161     }
10162     sptr<SceneSession> targetSession = nullptr;
10163     ret = GetAppMainSceneSession(targetSession, targetPersistentId);
10164     if (ret != WSError::WS_OK) {
10165         return ret;
10166     }
10167     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
10168         WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
10169             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
10170         return WSError::WS_ERROR_INVALID_CALLING;
10171     }
10172     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
10173         return WSError::WS_ERROR_INVALID_CALLING;
10174     }
10175     int32_t callingPid = IPCSkeleton::GetCallingPid();
10176     if (callingPid != targetSession->GetCallingPid()) {
10177         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
10178         return WSError::WS_ERROR_INVALID_CALLING;
10179     }
10180     targetSession->NotifyClick();
10181     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
10182     return RequestSessionFocus(targetPersistentId, false, reason);
10183 }
10184 
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)10185 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
10186 {
10187     sceneSession = GetSceneSession(persistentId);
10188     if (sceneSession == nullptr) {
10189         WLOGFE("session(%{public}d) is nullptr", persistentId);
10190         return WSError::WS_ERROR_INVALID_SESSION;
10191     }
10192     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10193         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
10194             WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
10195             return WSError::WS_ERROR_INVALID_CALLING;
10196         }
10197         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
10198         if (sceneSession == nullptr) {
10199             WLOGFE("session(%{public}d) parent is nullptr", persistentId);
10200             return WSError::WS_ERROR_INVALID_SESSION;
10201         }
10202     }
10203     return WSError::WS_OK;
10204 }
10205 
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)10206 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
10207     const float scaleParam)
10208 {
10209     auto sceneSession = GetSceneSession(persistentId);
10210     if (!sceneSession) {
10211         WLOGFE("get scene session is nullptr");
10212         return nullptr;
10213     }
10214 
10215     wptr<SceneSession> weakSceneSession(sceneSession);
10216     auto task = [this, persistentId, scaleParam, weakSceneSession]() {
10217         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
10218         auto scnSession = weakSceneSession.promote();
10219         std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
10220         if (scnSession == nullptr) {
10221             WLOGFE("session is nullptr");
10222             return pixelMap;
10223         }
10224 
10225         if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
10226             scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
10227             pixelMap = scnSession->Snapshot(false, scaleParam);
10228         }
10229         if (!pixelMap) {
10230             WLOGFI("get local snapshot pixelmap start");
10231             pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
10232         }
10233         return pixelMap;
10234     };
10235     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
10236 }
10237 
GetSceneSessionMap()10238 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
10239 {
10240     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
10241     {
10242         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10243         retSceneSessionMap = sceneSessionMap_;
10244     }
10245     EraseIf(retSceneSessionMap, [this](const auto& pair) {
10246         if (pair.second == nullptr) {
10247             return true;
10248         }
10249 
10250         if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
10251             if (pair.second->IsVisible()) {
10252                 return false;
10253             }
10254             return true;
10255         }
10256 
10257         if (pair.second->IsSystemInput()) {
10258             return false;
10259         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
10260             return false;
10261         }
10262 
10263         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
10264             return true;
10265         }
10266         return false;
10267     });
10268     return retSceneSessionMap;
10269 }
10270 
NotifyUpdateRectAfterLayout()10271 void SceneSessionManager::NotifyUpdateRectAfterLayout()
10272 {
10273     auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
10274     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
10275     if (transactionController) {
10276         rsTransaction = transactionController->GetRSTransaction();
10277     }
10278     auto task = [this, rsTransaction]() {
10279         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10280         for (auto& iter: sceneSessionMap_) {
10281             auto sceneSession = iter.second;
10282             if (sceneSession && sceneSession->IsDirtyWindow()) {
10283                 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
10284             }
10285         }
10286     };
10287     // need sync task since animation transcation need
10288     return taskScheduler_->PostAsyncTask(task);
10289 }
10290 
GetAllWindowLayoutInfo(DisplayId displayId,std::vector<sptr<WindowLayoutInfo>> & infos)10291 WMError SceneSessionManager::GetAllWindowLayoutInfo(DisplayId displayId,
10292     std::vector<sptr<WindowLayoutInfo>>& infos)
10293 {
10294     auto task = [this, displayId, &infos]() mutable {
10295         constexpr bool isVirtualDisplay = false;
10296         std::vector<sptr<SceneSession>> filteredSessions;
10297         FilterForGetAllWindowLayoutInfo(displayId, isVirtualDisplay, filteredSessions);
10298         for (const auto& session : filteredSessions) {
10299             Rect globalScaledRect;
10300             session->GetGlobalScaledRect(globalScaledRect);
10301             auto windowLayoutInfo = sptr<WindowLayoutInfo>::MakeSptr();
10302             windowLayoutInfo->rect = globalScaledRect;
10303             infos.emplace_back(windowLayoutInfo);
10304         }
10305         return WMError::WM_OK;
10306     };
10307     return taskScheduler_->PostSyncTask(task, __func__);
10308 }
10309 
FilterForGetAllWindowLayoutInfo(DisplayId displayId,bool isVirtualDisplay,std::vector<sptr<SceneSession>> & filteredSessions)10310 void SceneSessionManager::FilterForGetAllWindowLayoutInfo(DisplayId displayId, bool isVirtualDisplay,
10311     std::vector<sptr<SceneSession>>& filteredSessions)
10312 {
10313     {
10314         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10315         for (const auto& [_, session] : sceneSessionMap_) {
10316             if (session == nullptr) {
10317                 continue;
10318             }
10319             if (session->GetSessionGlobalRect().IsInvalid()) {
10320                 continue;
10321             }
10322             if (IsGetWindowLayoutInfoNeeded(session) && session->GetSessionProperty()->GetDisplayId() == displayId &&
10323                 session->GetVisibilityState() != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
10324                 filteredSessions.emplace_back(session);
10325             }
10326         }
10327     }
10328     std::sort(filteredSessions.begin(), filteredSessions.end(),
10329               [](const sptr<SceneSession>& lhs, const sptr<SceneSession>& rhs) {
10330                   return lhs->GetZOrder() > rhs->GetZOrder();
10331               });
10332 }
10333 
IsGetWindowLayoutInfoNeeded(const sptr<SceneSession> & session) const10334 bool SceneSessionManager::IsGetWindowLayoutInfoNeeded(const sptr<SceneSession>& session) const
10335 {
10336     constexpr int32_t GROUP_ONE = 1;
10337     std::string name = session->GetWindowName();
10338     std::regex pattern("^(.*?)(\\d*)$"); // Remove last digit
10339     std::smatch matches;
10340     name = std::regex_search(name, matches, pattern) ? matches[GROUP_ONE] : name;
10341     return !session->GetSessionInfo().isSystem_ || LAYOUT_INFO_WHITELIST.find(name) != LAYOUT_INFO_WHITELIST.end();
10342 }
10343 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)10344 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
10345 {
10346     if (!SessionPermission::IsSystemCalling()) {
10347         WLOGFE("GetVisibilityWindowInfo permission denied!");
10348         return WMError::WM_ERROR_NOT_SYSTEM_APP;
10349     }
10350     auto task = [this, &infos]() {
10351         for (auto [surfaceId, _] : lastVisibleData_) {
10352             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
10353             if (session == nullptr) {
10354                 continue;
10355             }
10356             WSRect hostRect = session->GetSessionRect();
10357             Rect rect = {hostRect.posX_, hostRect.posY_,
10358                          static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
10359             auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
10360                                                 session->GetSessionProperty());
10361             infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
10362                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
10363                 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
10364                 session->IsFocused()));
10365         }
10366         return WMError::WM_OK;
10367     };
10368     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
10369 }
10370 
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)10371 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
10372 {
10373     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10374     for (const auto& [id, session] : sceneSessionMap_) {
10375         if (session == nullptr) {
10376             continue;
10377         }
10378         uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
10379         windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
10380     }
10381 }
10382 
FlushWindowInfoToMMI(const bool forceFlush)10383 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
10384 {
10385     auto task = [this, forceFlush] {
10386         if (isUserBackground_) {
10387             TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
10388             return;
10389         }
10390         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
10391         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
10392     };
10393     taskScheduler_->PostAsyncTask(task);
10394 }
10395 
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)10396 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
10397     int32_t& parentId)
10398 {
10399     // This function should be called in task
10400     auto iter = extSessionInfoMap_.find(token);
10401     if (iter == extSessionInfoMap_.end()) {
10402         return false;
10403     }
10404     persistentId = iter->second.persistentId;
10405     parentId = iter->second.parentId;
10406     return true;
10407 }
10408 
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession,bool isConstrainedModal)10409 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession, bool isConstrainedModal)
10410 {
10411     auto task = [this, remoteExtSession, isConstrainedModal]() {
10412         auto iter = remoteExtSessionMap_.find(remoteExtSession);
10413         if (iter == remoteExtSessionMap_.end()) {
10414             TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
10415             return;
10416         }
10417         auto abilityToken = iter->second;
10418         int32_t persistentId = INVALID_SESSION_ID;
10419         int32_t parentId = INVALID_SESSION_ID;
10420         if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
10421             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10422             return;
10423         }
10424 
10425         TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
10426             persistentId, parentId);
10427         auto sceneSession = GetSceneSession(parentId);
10428         if (sceneSession != nullptr) {
10429             auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10430             sceneSession->RemoveExtWindowFlags(persistentId);
10431             if (oldFlags.hideNonSecureWindowsFlag) {
10432                 HandleSecureSessionShouldHide(sceneSession);
10433             }
10434             if (oldFlags.waterMarkFlag) {
10435                 CheckAndNotifyWaterMarkChangedResult();
10436             }
10437             if (oldFlags.privacyModeFlag) {
10438                 UpdatePrivateStateAndNotify(parentId);
10439             }
10440             if (!isConstrainedModal) {
10441                 sceneSession->RemoveNormalModalUIExtension(persistentId);
10442             }
10443             sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
10444             sceneSession->RemoveExtensionTokenInfo(abilityToken);
10445         } else {
10446             ExtensionWindowFlags actions;
10447             actions.SetAllActive();
10448             HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
10449         }
10450         extSessionInfoMap_.erase(iter->second);
10451         remoteExtSessionMap_.erase(iter);
10452     };
10453     taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
10454 }
10455 
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)10456 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
10457 {
10458     auto pid = IPCSkeleton::GetCallingRealPid();
10459     auto task = [this, token, pid, rect]() {
10460         int32_t persistentId = INVALID_SESSION_ID;
10461         int32_t parentId = INVALID_SESSION_ID;
10462         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10463             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10464             return;
10465         }
10466         TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
10467             "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
10468             pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10469         auto parentSession = GetSceneSession(parentId);
10470         if (parentSession) {
10471             auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
10472             auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
10473             Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
10474             ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
10475             TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
10476                 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
10477                 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
10478                 parentSession->GetSessionGlobalRect().ToString().c_str());
10479             parentSession->UpdateNormalModalUIExtension(extensionInfo);
10480         }
10481     };
10482     taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
10483 }
10484 
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)10485 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
10486 {
10487     auto pid = IPCSkeleton::GetCallingRealPid();
10488     auto task = [this, token, pid, posX, posY]() {
10489         int32_t persistentId = INVALID_SESSION_ID;
10490         int32_t parentId = INVALID_SESSION_ID;
10491         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10492             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10493             return;
10494         }
10495         TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
10496             "parentId=%{public}d", pid, persistentId, parentId);
10497         auto parentSession = GetSceneSession(parentId);
10498         if (parentSession) {
10499             auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
10500             if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
10501                 modalUIExtensionEventInfo.value().persistentId == persistentId) {
10502                 parentSession->ProcessPointDownSession(posX, posY);
10503             }
10504         }
10505     };
10506     taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
10507 }
10508 
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId,bool isConstrainedModal)10509 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
10510     const sptr<IRemoteObject>& token, uint64_t surfaceNodeId, bool isConstrainedModal)
10511 {
10512     auto pid = IPCSkeleton::GetCallingRealPid();
10513     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
10514     auto task = [this, sessionStage, token, surfaceNodeId, isConstrainedModal, pid, callingTokenId]() {
10515         if (sessionStage == nullptr || token == nullptr) {
10516             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10517             return;
10518         }
10519         auto remoteExtSession = sessionStage->AsObject();
10520         if (remoteExtSession == nullptr) {
10521             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10522             return;
10523         }
10524         if (extensionDeath_ == nullptr) {
10525             TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
10526             return;
10527         }
10528         if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
10529             TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
10530             return;
10531         }
10532 
10533         AAFwk::UIExtensionSessionInfo info;
10534         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
10535         if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
10536             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
10537             return;
10538         }
10539 
10540         int32_t persistentId = info.persistentId;
10541         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
10542         UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
10543         TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
10544             "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
10545             surfaceNodeId, pid);
10546 
10547         remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
10548         extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
10549 
10550         auto parentSession = GetSceneSession(parentId);
10551         if (!parentSession) {
10552             TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
10553             return;
10554         }
10555 
10556         UIExtensionTokenInfo tokenInfo;
10557         tokenInfo.abilityToken = token;
10558         tokenInfo.callingTokenId = callingTokenId;
10559         tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
10560             info.extensionAbilityType);
10561         parentSession->AddExtensionTokenInfo(tokenInfo);
10562         parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
10563         if (usage == UIExtensionUsage::MODAL) {
10564             ExtensionWindowEventInfo extensionInfo {
10565                 .persistentId = persistentId,
10566                 .pid = pid,
10567             };
10568             if (!isConstrainedModal) {
10569                 parentSession->AddNormalModalUIExtension(extensionInfo);
10570             }
10571         }
10572     };
10573     taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
10574 }
10575 
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,bool isConstrainedModal)10576 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
10577     const sptr<IRemoteObject>& token, bool isConstrainedModal)
10578 {
10579     TLOGI(WmsLogTag::WMS_UIEXT, "in");
10580     auto task = [this, sessionStage, token, isConstrainedModal]() {
10581         if (sessionStage == nullptr || token == nullptr) {
10582             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10583             return;
10584         }
10585         auto remoteExtSession = sessionStage->AsObject();
10586         if (remoteExtSession == nullptr) {
10587             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10588             return;
10589         }
10590         auto iter = remoteExtSessionMap_.find(remoteExtSession);
10591         if (iter == remoteExtSessionMap_.end() || iter->second != token) {
10592             TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
10593             return;
10594         }
10595 
10596         DestroyExtensionSession(remoteExtSession, isConstrainedModal);
10597     };
10598     taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
10599 }
10600 
CalculateCombinedExtWindowFlags()10601 void SceneSessionManager::CalculateCombinedExtWindowFlags()
10602 {
10603     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
10604     combinedExtWindowFlags_.bitData = 0;
10605     for (const auto& iter: extWindowFlagsMap_) {
10606         combinedExtWindowFlags_.bitData |= iter.second.bitData;
10607     }
10608     specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
10609 }
10610 
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10611 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
10612     ExtensionWindowFlags actions)
10613 {
10614     auto iter = extWindowFlagsMap_.find(persistentId);
10615     // Each flag is false when inactive, 0 means all flags are inactive
10616     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
10617     ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
10618     if (newFlags.bitData == 0) {
10619         extWindowFlagsMap_.erase(persistentId);
10620     } else {
10621         extWindowFlagsMap_[persistentId] = newFlags;
10622     }
10623     CalculateCombinedExtWindowFlags();
10624 }
10625 
HideNonSecureFloatingWindows()10626 void SceneSessionManager::HideNonSecureFloatingWindows()
10627 {
10628     bool shouldHide = false;
10629     {
10630         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10631         for (const auto& iter: sceneSessionMap_) {
10632             auto& session = iter.second;
10633             if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
10634                 shouldHide = true;
10635                 break;
10636             }
10637         }
10638     }
10639     if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
10640         TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
10641         shouldHide = true;
10642     }
10643     if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
10644         return;
10645     }
10646 
10647     shouldHideNonSecureFloatingWindows_.store(shouldHide);
10648     for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
10649         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
10650             session->NotifyForceHideChange(shouldHide);
10651             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10652                 session->GetWindowName().c_str(), persistentId, shouldHide);
10653         }
10654     }
10655 }
10656 
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)10657 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
10658 {
10659     // don't let sub-window show when switching secure host window to background
10660     if (!sceneSession->IsSessionForeground()) {
10661         return;
10662     }
10663 
10664     auto parentId = sceneSession->GetPersistentId();
10665     bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
10666     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10667     for (const auto& [persistentId, session] : sceneSessionMap_) {
10668         if (!session) {
10669             continue;
10670         }
10671         auto property = session->GetSessionProperty();
10672         if (!property || property->GetParentPersistentId() != parentId) {
10673             continue;
10674         }
10675 
10676         if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
10677             session->NotifyForceHideChange(shouldHide);
10678             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10679                 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
10680         }
10681     }
10682 }
10683 
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)10684 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
10685 {
10686     if (sceneSession == nullptr) {
10687         TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
10688         return WSError::WS_ERROR_INVALID_SESSION;
10689     }
10690 
10691     HideNonSecureFloatingWindows();
10692     HideNonSecureSubWindows(sceneSession);
10693     return WSError::WS_OK;
10694 }
10695 
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10696 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
10697     ExtensionWindowFlags actions)
10698 {
10699     UpdateSpecialExtWindowFlags(persistentId, flags, actions);
10700     if (actions.waterMarkFlag) {
10701         CheckAndNotifyWaterMarkChangedResult();
10702     }
10703     if (actions.hideNonSecureWindowsFlag) {
10704         HideNonSecureFloatingWindows();
10705     }
10706     if (actions.privacyModeFlag) {
10707         UpdatePrivateStateAndNotifyForAllScreens();
10708     }
10709 }
10710 
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)10711 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
10712 {
10713     TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
10714     if (!SessionPermission::IsSystemCalling()) {
10715         TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
10716         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10717     }
10718     const auto callingPid = IPCSkeleton::GetCallingRealPid();
10719     auto task = [this, persistentId, shouldHide, callingPid]() {
10720         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10721         auto iter = sceneSessionMap_.find(persistentId);
10722         if (iter == sceneSessionMap_.end()) {
10723             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
10724                 persistentId);
10725             return WSError::WS_ERROR_INVALID_SESSION;
10726         }
10727         auto sceneSession = iter->second;
10728         if (sceneSession == nullptr) {
10729             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
10730             return WSError::WS_ERROR_NULLPTR;
10731         }
10732         if (callingPid != sceneSession->GetCallingPid()) {
10733             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
10734             return WSError::WS_ERROR_INVALID_PERMISSION;
10735         }
10736         sceneSession->SetShouldHideNonSecureWindows(shouldHide);
10737         return HandleSecureSessionShouldHide(sceneSession);
10738     };
10739 
10740     taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
10741     return WSError::WS_OK;
10742 }
10743 
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const10744 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
10745 {
10746     auto ret = WSError::WS_OK;
10747     bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
10748     if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
10749         actions.hideNonSecureWindowsFlag = false;
10750         actions.waterMarkFlag = false;
10751         TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
10752         ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
10753     }
10754     auto needPrivacyWindow = actions.privacyModeFlag;
10755     if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
10756         actions.privacyModeFlag = false;
10757         TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
10758         ret = WSError::WS_ERROR_INVALID_PERMISSION;
10759     }
10760     return ret;
10761 }
10762 
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)10763 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
10764     uint32_t extWindowActions)
10765 {
10766     ExtensionWindowFlags actions(extWindowActions);
10767     auto ret = CheckExtWindowFlagsPermission(actions);
10768     if (actions.bitData == 0) {
10769         return ret;
10770     }
10771 
10772     ExtensionWindowFlags flags(extWindowFlags);
10773     auto task = [this, token, flags, actions]() {
10774         int32_t persistentId = INVALID_SESSION_ID;
10775         int32_t parentId = INVALID_SESSION_ID;
10776         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10777             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10778             return WSError::WS_ERROR_INVALID_OPERATION;
10779         }
10780 
10781         TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
10782             "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
10783         auto sceneSession = GetSceneSession(parentId);
10784         if (sceneSession == nullptr) {
10785             TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
10786                 parentId);
10787             HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
10788             return WSError::WS_OK;
10789         }
10790 
10791         auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10792         sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
10793         auto newFlags = sceneSession->GetCombinedExtWindowFlags();
10794         if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
10795             HandleSecureSessionShouldHide(sceneSession);
10796         }
10797         if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
10798             CheckAndNotifyWaterMarkChangedResult();
10799         }
10800         if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
10801             UpdatePrivateStateAndNotify(parentId);
10802         }
10803         return WSError::WS_OK;
10804     };
10805 
10806     taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
10807     return ret;
10808 }
10809 
GetHostWindowRect(int32_t hostWindowId,Rect & rect)10810 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
10811 {
10812     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
10813     if (!SessionPermission::IsSystemCalling()) {
10814         TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
10815         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10816     }
10817     auto task = [this, hostWindowId, &rect]() {
10818         auto sceneSession = GetSceneSession(hostWindowId);
10819         if (sceneSession == nullptr) {
10820             TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
10821             return WSError::WS_ERROR_INVALID_SESSION;
10822         }
10823         WSRect hostRect = sceneSession->GetSessionRect();
10824         rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
10825         return WSError::WS_OK;
10826     };
10827     taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
10828     return WSError::WS_OK;
10829 }
10830 
ReclaimPurgeableCleanMem()10831 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
10832 {
10833 #ifdef MEMMGR_WINDOW_ENABLE
10834     return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
10835 #else
10836     return -1;
10837 #endif
10838 }
10839 
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)10840 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
10841     const std::vector<VisibleWindowNumInfo>& currentInfo)
10842 {
10843     if (lastInfo.size() != currentInfo.size()) {
10844         WLOGFE("last and current info is not Same");
10845         return false;
10846     }
10847     int sizeOfLastInfo = static_cast<int>(lastInfo.size());
10848     for (int i = 0; i < sizeOfLastInfo; i++) {
10849         if (lastInfo[i].displayId != currentInfo[i].displayId ||
10850             lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
10851             WLOGFE("last and current visible window num is not Same");
10852             return false;
10853         }
10854     }
10855     return true;
10856 }
10857 
CacVisibleWindowNum()10858 void SceneSessionManager::CacVisibleWindowNum()
10859 {
10860     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10861     {
10862         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10863         sceneSessionMapCopy = sceneSessionMap_;
10864     }
10865     std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
10866     bool isFullScreen = true;
10867     for (const auto& elem : sceneSessionMapCopy) {
10868         auto curSession = elem.second;
10869         if (curSession == nullptr) {
10870             continue;
10871         }
10872         bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
10873             curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
10874         if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10875             continue;
10876         }
10877 
10878         bool isWindowVisible = curSession->GetRSVisible();
10879         if (isWindowVisible) {
10880             auto windowMode = curSession->GetWindowMode();
10881             if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
10882                 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
10883                 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
10884                 isFullScreen = false;
10885             }
10886             int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
10887             auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10888                 [=](const VisibleWindowNumInfo& info) {
10889                     return (static_cast<int32_t>(info.displayId)) == displayId;
10890             });
10891             if (it == visibleWindowNumInfo.end()) {
10892                 visibleWindowNumInfo.push_back({displayId, 1});
10893             } else {
10894                 it->visibleWindowNum++;
10895             }
10896         }
10897     }
10898     if (isFullScreen) {
10899         std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10900                       [](auto& info) { info.visibleWindowNum = 1; });
10901     }
10902     std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
10903     if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10904         SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10905         lastInfo_ = visibleWindowNumInfo;
10906     }
10907 }
10908 
ReportWindowProfileInfos()10909 void SceneSessionManager::ReportWindowProfileInfos()
10910 {
10911     enum class WindowVisibleState : int32_t {
10912         FOCUSBLE = 0,
10913         VISIBLE,
10914         MINIMIZED,
10915         OCCLUSION
10916     };
10917     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10918     {
10919         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10920         sceneSessionMapCopy = sceneSessionMap_;
10921     }
10922     auto focusWindowId = GetFocusedSessionId();
10923     for (const auto& elem : sceneSessionMapCopy) {
10924         auto curSession = elem.second;
10925         if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10926             curSession->GetWindowType() !=  WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10927             continue;
10928         }
10929         WindowProfileInfo windowProfileInfo;
10930         windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10931         windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10932             curSession->GetSessionProperty()->GetDisplayId());
10933         windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10934         if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10935             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10936         } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10937             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10938         } else if (!curSession->GetRSVisible()) {
10939             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10940         } else {
10941             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10942         }
10943         WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10944         WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10945             "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10946             windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10947             windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10948     }
10949 }
10950 
GetCustomDecorHeight(int32_t persistentId)10951 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10952 {
10953     int32_t height = 0;
10954     auto sceneSession = GetSceneSession(persistentId);
10955     if (sceneSession == nullptr) {
10956         TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10957         return 0;
10958     }
10959     height = sceneSession->GetCustomDecorHeight();
10960     TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10961     return height;
10962 }
10963 
RemoveFailRecoveredSession()10964 void SceneSessionManager::RemoveFailRecoveredSession()
10965 {
10966     for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10967         auto sceneSession = GetSceneSession(persistentId);
10968         if (sceneSession == nullptr) {
10969             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10970             continue;
10971         }
10972         if (!sceneSession->IsRecovered()) {
10973             TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10974             continue;
10975         }
10976         const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10977         if (!scnSessionInfo) {
10978             TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr,persistentId = %{public}d", persistentId);
10979             continue;
10980         }
10981         TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10982         sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10983     }
10984     failRecoveredPersistentIdSet_.clear();
10985 }
10986 
GetDisplayRegion(DisplayId displayId)10987 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10988 {
10989     if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10990         return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10991     }
10992     TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10993     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10994     if (display == nullptr) {
10995         TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10996         return nullptr;
10997     }
10998     auto displayInfo = display->GetDisplayInfo();
10999     if (displayInfo == nullptr) {
11000         TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
11001         return nullptr;
11002     }
11003     int32_t displayWidth = displayInfo->GetWidth();
11004     int32_t displayHeight = displayInfo->GetHeight();
11005     if (displayWidth == 0 || displayHeight == 0) {
11006         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
11007         return nullptr;
11008     }
11009 
11010     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
11011     auto region = std::make_shared<SkRegion>(rect);
11012     displayRegionMap_[displayId] = region;
11013     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
11014     return std::make_shared<SkRegion>(rect);
11015 }
11016 
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)11017 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
11018 {
11019     if (displayInfo == nullptr) {
11020         TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
11021         return;
11022     }
11023     auto displayId = displayInfo->GetDisplayId();
11024     int32_t displayWidth = displayInfo->GetWidth();
11025     int32_t displayHeight = displayInfo->GetHeight();
11026     if (displayWidth == 0 || displayHeight == 0) {
11027         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
11028         return;
11029     }
11030     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
11031     auto region = std::make_shared<SkRegion>(rect);
11032     displayRegionMap_[displayId] = region;
11033     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
11034 }
11035 
GetDisplaySizeById(DisplayId displayId,int32_t & displayWidth,int32_t & displayHeight)11036 bool SceneSessionManager::GetDisplaySizeById(DisplayId displayId, int32_t& displayWidth, int32_t& displayHeight)
11037 {
11038     auto region = GetDisplayRegion(displayId);
11039     if (region == nullptr) {
11040         TLOGW(WmsLogTag::WMS_LAYOUT, "failed, displayId:%{public}" PRIu64, displayId);
11041         return false;
11042     }
11043     const SkIRect& rect = region->getBounds();
11044     displayWidth = rect.fRight;
11045     displayHeight = rect.fBottom;
11046     return true;
11047 }
11048 
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)11049 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
11050 {
11051     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11052     for (const auto& item : sceneSessionMap_) {
11053         auto sceneSession = item.second;
11054         if (sceneSession == nullptr) {
11055             continue;
11056         }
11057         if (Session::IsScbCoreEnabled()) {
11058             if (!sceneSession->IsVisibleForAccessibility()) {
11059                 continue;
11060             }
11061         } else {
11062             if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
11063                 continue;
11064             }
11065         }
11066         if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
11067             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
11068             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
11069             continue;
11070         }
11071         sceneSessionList.push_back(sceneSession);
11072     }
11073 }
11074 
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)11075 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
11076     std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
11077 {
11078     for (const auto& sceneSession : sceneSessionList) {
11079         if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
11080             TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
11081         }
11082     }
11083 }
11084 
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)11085 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
11086 {
11087     std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
11088         return a->GetZOrder() > b->GetZOrder();
11089     });
11090     std::vector<sptr<SceneSession>> result;
11091     std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
11092     for (const auto& sceneSession : sceneSessionList) {
11093         if (sceneSession == nullptr) {
11094             TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
11095             continue;
11096         }
11097         auto sessionProperty = sceneSession->GetSessionProperty();
11098         if (sessionProperty == nullptr) {
11099             TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
11100             continue;
11101         }
11102         std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
11103         auto displayId = sessionProperty->GetDisplayId();
11104         if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
11105             unaccountedSpace = unaccountedSpaceMap[displayId];
11106         } else {
11107             unaccountedSpace = GetDisplayRegion(displayId);
11108             if (unaccountedSpace == nullptr) {
11109                 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
11110                 continue;
11111             }
11112             unaccountedSpaceMap[displayId] = unaccountedSpace;
11113         }
11114         WSRect wsRect = sceneSession->GetSessionRect();
11115         SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
11116                               .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
11117         SkRegion windowRegion(windowBounds);
11118         if (unaccountedSpace->quickReject(windowRegion)) {
11119             TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
11120                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
11121             continue;
11122         }
11123         if (!unaccountedSpace->intersects(windowRegion)) {
11124             TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
11125                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
11126             continue;
11127         }
11128         result.push_back(sceneSession);
11129         unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
11130         if (unaccountedSpace->isEmpty()) {
11131             break;
11132         }
11133     }
11134     sceneSessionList = result;
11135 }
11136 
NotifyAllAccessibilityInfo()11137 void SceneSessionManager::NotifyAllAccessibilityInfo()
11138 {
11139     if (isUserBackground_) {
11140         TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
11141         return;
11142     }
11143     std::vector<sptr<SceneSession>> sceneSessionList;
11144     GetAllSceneSessionForAccessibility(sceneSessionList);
11145     FilterSceneSessionCovered(sceneSessionList);
11146 
11147     std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
11148     FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
11149 
11150     for (const auto& item : accessibilityInfo) {
11151         TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, \
11152             bundle=%{public}s, bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
11153             item->wid_, item->innerWid_, item->bundleName_.c_str(),
11154             item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
11155         for (const auto& rect : item->touchHotAreas_) {
11156             TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d," \
11157             "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
11158         }
11159     }
11160 
11161     SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
11162         WindowUpdateType::WINDOW_UPDATE_ALL);
11163 }
11164 
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)11165 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
11166     const sptr<WindowSessionProperty>& property)
11167 {
11168     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
11169     if (property == nullptr) {
11170         return windowStatus;
11171     }
11172     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
11173         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
11174         if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
11175             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
11176         }
11177     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
11178         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
11179     } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
11180         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
11181     } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
11182         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
11183     }
11184     return windowStatus;
11185 }
11186 
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)11187 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
11188 {
11189     if (!SessionPermission::IsStartedByInputMethod()) {
11190         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
11191         return WMError::WM_ERROR_INVALID_PERMISSION;
11192     }
11193     auto scnSession = GetSceneSession(persistentId);
11194     if (scnSession == nullptr) {
11195         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
11196         return WMError::WM_ERROR_NULLPTR;
11197     }
11198 
11199     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
11200         persistentId, scnSession->GetWindowType());
11201 
11202     auto sessionProperty = scnSession->GetSessionProperty();
11203     if (sessionProperty == nullptr) {
11204         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
11205         return WMError::WM_ERROR_INVALID_WINDOW;
11206     }
11207     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
11208     auto callingSession = GetSceneSession(callingWindowId);
11209     if (callingSession == nullptr) {
11210         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
11211         callingSession = GetSceneSession(focusedSessionId_);
11212         if (callingSession == nullptr) {
11213             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
11214             return WMError::WM_ERROR_INVALID_WINDOW;
11215         }
11216     }
11217     if (callingSession->IsSystemSession()) {
11218         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
11219     } else {
11220         windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
11221             callingSession->GetSessionProperty());
11222     }
11223     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
11224         persistentId, windowStatus);
11225     return WMError::WM_OK;
11226 }
11227 
GetCallingWindowRect(int32_t persistentId,Rect & rect)11228 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
11229 {
11230     if (!SessionPermission::IsStartedByInputMethod()) {
11231         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
11232         return WMError::WM_ERROR_INVALID_PERMISSION;
11233     }
11234     auto scnSession = GetSceneSession(persistentId);
11235     if (scnSession == nullptr) {
11236         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
11237         return WMError::WM_ERROR_NULLPTR;
11238     }
11239     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
11240         persistentId, scnSession->GetWindowType());
11241     auto sessionProperty = scnSession->GetSessionProperty();
11242     if (sessionProperty == nullptr) {
11243         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
11244         return WMError::WM_ERROR_INVALID_WINDOW;
11245     }
11246     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
11247     auto callingSession = GetSceneSession(callingWindowId);
11248     if (callingSession == nullptr) {
11249         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
11250         callingSession = GetSceneSession(focusedSessionId_);
11251         if (callingSession == nullptr) {
11252             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
11253             return WMError::WM_ERROR_INVALID_WINDOW;
11254         }
11255     }
11256     WSRect sessionRect = callingSession->GetSessionRect();
11257     rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
11258     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
11259         "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
11260     return WMError::WM_OK;
11261 }
11262 
GetWindowModeType(WindowModeType & windowModeType)11263 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
11264 {
11265     if (!SessionPermission::IsSACalling()) {
11266         WLOGFE("GetWindowModeType permission denied!");
11267         return WMError::WM_ERROR_INVALID_PERMISSION;
11268     }
11269     windowModeType = CheckWindowModeType();
11270     return WMError::WM_OK;
11271 }
11272 
GetWindowStyleType(WindowStyleType & windowStyleType)11273 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
11274 {
11275     if (!SessionPermission::IsSACalling()) {
11276         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
11277         return WMError::WM_ERROR_INVALID_PERMISSION;
11278     }
11279     auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
11280     if (isPC) {
11281         windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
11282         return WMError::WM_OK;
11283     }
11284     windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
11285         WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
11286     return WMError::WM_OK;
11287 }
11288 
CheckSceneZOrder()11289 void SceneSessionManager::CheckSceneZOrder()
11290 {
11291     auto task = [this]() {
11292         AnomalyDetection::SceneZOrderCheckProcess();
11293     };
11294     taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
11295 }
11296 
NotifyEnterRecentTask(bool enterRecent)11297 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
11298 {
11299     TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
11300     enterRecent_.store(enterRecent);
11301     SetSystemAnimatedScenes(enterRecent ?
11302         SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
11303     auto task = [this] {
11304         for (auto persistentId : gestureBackEnableWindowIdSet_) {
11305             auto sceneSession = GetSceneSession(persistentId);
11306             if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
11307                 continue;
11308             }
11309             UpdateGestureBackEnabled(persistentId);
11310         }
11311     };
11312     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
11313     return WSError::WS_OK;
11314 }
11315 
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)11316 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
11317 {
11318     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
11319         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11320         return WMError::WM_ERROR_INVALID_PERMISSION;
11321     }
11322 
11323     if (!topNInfo.empty() || (topNum <= 0)) {
11324         return WMError::WM_ERROR_INVALID_PARAM;
11325     }
11326 
11327     TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
11328     auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
11329         if (session == nullptr) {
11330             return false;
11331         }
11332 
11333         if (topNum == 0) {
11334             return true;
11335         }
11336 
11337         if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
11338             TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
11339             return false;
11340         }
11341 
11342         MainWindowInfo info;
11343         info.pid_ = session->GetCallingPid();
11344         info.bundleName_ = session->GetSessionInfo().bundleName_;
11345         topNInfo.push_back(info);
11346         topNum--;
11347         TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
11348             topNum, info.pid_, info.bundleName_.c_str());
11349         return false;
11350     };
11351     TraverseSessionTree(func, true);
11352 
11353     return WMError::WM_OK;
11354 }
11355 
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)11356 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
11357     int32_t x, int32_t y, std::vector<int32_t>& windowIds)
11358 {
11359     TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
11360           displayId, windowNumber, x, y);
11361     if (displayId == DISPLAY_ID_INVALID) {
11362         TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
11363         return WMError::WM_ERROR_INVALID_PARAM;
11364     }
11365     bool findAllWindow = windowNumber <= 0;
11366     bool checkPoint = (x >= 0 && y >= 0);
11367     std::string callerBundleName = SessionPermission::GetCallingBundleName();
11368     auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
11369         findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
11370         if (session == nullptr) {
11371             return false;
11372         }
11373         auto sessionProperty = session->GetSessionProperty();
11374         if (sessionProperty == nullptr) {
11375             return false;
11376         }
11377         if (!findAllWindow && windowNumber == 0) {
11378             return true;
11379         }
11380         bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
11381         bool isSameDisplayId = sessionProperty->GetDisplayId() == displayId;
11382         bool isRsVisible = session->GetRSVisible();
11383         WSRect windowRect = session->GetSessionRect();
11384         bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
11385         TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
11386                " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
11387                session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
11388                sessionProperty->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
11389         if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
11390             return false;
11391         }
11392         windowIds.emplace_back(session->GetPersistentId());
11393         windowNumber--;
11394         return false;
11395     };
11396     auto task = [this, func = std::move(func)] {
11397         TraverseSessionTree(func, true);
11398         return WMError::WM_OK;
11399     };
11400     return taskScheduler_->PostSyncTask(task, __func__);
11401 }
11402 
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const11403 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
11404 {
11405     if (!infos.empty()) {
11406         TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
11407         return WMError::WM_ERROR_INVALID_PARAM;
11408     }
11409     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11410         TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
11411         return WMError::WM_ERROR_INVALID_PERMISSION;
11412     }
11413     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11414     for (const auto& iter : sceneSessionMap_) {
11415         auto& session = iter.second;
11416         if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
11417             continue;
11418         }
11419         MainWindowInfo info;
11420         auto abilityInfo = session->GetSessionInfo().abilityInfo;
11421         info.pid_ = session->GetCallingPid();
11422         info.bundleName_ = session->GetSessionInfo().bundleName_;
11423         info.persistentId_ = session->GetPersistentId();
11424         if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
11425             TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
11426             info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
11427             infos.push_back(info);
11428         } else if (abilityInfo != nullptr) {
11429             info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
11430             infos.push_back(info);
11431             TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
11432                 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
11433                 info.bundleName_.c_str(), info.bundleType_);
11434         }
11435     }
11436     return WMError::WM_OK;
11437 }
11438 
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)11439 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
11440     std::vector<int32_t>& clearFailedIds)
11441 {
11442     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11443         TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
11444         return WMError::WM_ERROR_INVALID_PERMISSION;
11445     }
11446     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
11447         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
11448         return WMError::WM_ERROR_INVALID_PERMISSION;
11449     }
11450     clearFailedIds.clear();
11451     for (const auto persistentId : persistentIds) {
11452         auto sceneSession = GetSceneSession(persistentId);
11453         if (sceneSession == nullptr) {
11454             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
11455             clearFailedIds.push_back(persistentId);
11456             continue;
11457         }
11458         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11459             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11460             clearFailedIds.push_back(persistentId);
11461             continue;
11462         }
11463         sceneSession->Clear();
11464         TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
11465     }
11466     return WMError::WM_OK;
11467 }
11468 
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)11469 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
11470     bool enable)
11471 {
11472     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
11473         width, height, density, enable);
11474 
11475     DMHookInfo dmHookInfo;
11476     dmHookInfo.width_ = width;
11477     dmHookInfo.height_ = height;
11478     dmHookInfo.density_ = density;
11479     dmHookInfo.rotation_ = 0;
11480     dmHookInfo.enableHookRotation_ = false;
11481     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11482     return WMError::WM_OK;
11483 }
11484 
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)11485 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
11486 {
11487     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
11488         "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
11489         hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
11490 
11491     DMHookInfo dmHookInfo;
11492     dmHookInfo.width_ = hookInfo.width_;
11493     dmHookInfo.height_ = hookInfo.height_;
11494     dmHookInfo.density_ = hookInfo.density_;
11495     dmHookInfo.rotation_ = hookInfo.rotation_;
11496     dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
11497     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11498     return WMError::WM_OK;
11499 }
11500 
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)11501 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
11502 {
11503     SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
11504 }
11505 
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)11506 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
11507 {
11508     ScreenFoldData screenFoldData;
11509     WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
11510     if (ret != WMError::WM_OK) {
11511         return ret;
11512     }
11513     return CheckAndReportScreenFoldStatus(screenFoldData);
11514 }
11515 
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)11516 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
11517     ScreenFoldData& screenFoldData)
11518 {
11519     if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
11520         TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
11521         return WMError::WM_DO_NOTHING;
11522     }
11523 
11524     screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
11525     screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
11526     screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
11527     screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
11528     screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
11529     if (!screenFoldData.GetTypeCThermalWithUtil()) {
11530         TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
11531         return WMError::WM_DO_NOTHING;
11532     }
11533     AppExecFwk::ElementName element = {};
11534     WSError ret = GetFocusSessionElement(element);
11535     if (ret != WSError::WS_OK) {
11536         TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
11537         return WMError::WM_DO_NOTHING;
11538     }
11539     screenFoldData.SetFocusedPkgName(element.GetURI());
11540     return WMError::WM_OK;
11541 }
11542 
CheckAndReportScreenFoldStatus(ScreenFoldData & data)11543 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
11544 {
11545     static ScreenFoldData lastScreenHalfFoldData;
11546     if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11547         lastScreenHalfFoldData = data;
11548         return WMError::WM_DO_NOTHING;
11549     }
11550     WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
11551     if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11552         if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
11553             lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
11554         } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
11555             // if stay at half-fold less than 15s, combine this change with last
11556             data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
11557             data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
11558             data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
11559         }
11560         lastScreenHalfFoldData.SetInvalid();
11561     }
11562     WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
11563     return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
11564         currentScreenFoldStatusReportRet;
11565 }
11566 
11567 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)11568 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
11569 {
11570     if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
11571         return WMError::WM_DO_NOTHING;
11572     }
11573 
11574     int32_t ret = HiSysEventWrite(
11575         OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
11576         "FOLDSCREEN_STATE_CHANGE",
11577         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
11578         "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
11579         "LASTFOLDSTATE", data.currentScreenFoldStatus_,
11580         "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
11581         "STATE", -1,
11582         "TIME", data.currentScreenFoldStatusDuration_,
11583         "ROTATION", data.screenRotation_,
11584         "PACKAGE", data.focusedPackageName_,
11585         "ANGLE", data.postureAngle_,
11586         "TYPECTHERMAL", data.typeCThermal_,
11587         "SCREENTHERMAL", -1,
11588         "SCANGLE", -1,
11589         "ISTENT", -1);
11590     if (ret != 0) {
11591         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
11592         return WMError::WM_DO_NOTHING;
11593     }
11594     return WMError::WM_OK;
11595 }
11596 
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userid)11597 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
11598 {
11599     if (currentUserId_ != static_cast<int32_t>(userid)) {
11600         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64,
11601             currentUserId_.load(), userid);
11602         return;
11603     }
11604     if (secExtensionData == nullptr) {
11605         TLOGE(WmsLogTag::WMS_EVENT, "invalid secExtensionData");
11606         return;
11607     }
11608     auto secSurfaceInfoMap = secExtensionData->GetSecData();
11609     auto task = [secSurfaceInfoMap]()-> WSError {
11610         SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
11611         return WSError::WS_OK;
11612     };
11613     taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
11614 }
11615 
RegisterSecSurfaceInfoListener()11616 void SceneSessionManager::RegisterSecSurfaceInfoListener()
11617 {
11618     auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
11619         this->UpdateSecSurfaceInfo(secExtensionData, userid);
11620     };
11621     TLOGI(WmsLogTag::WMS_EVENT, "in");
11622     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
11623         TLOGE(WmsLogTag::WMS_EVENT, "failed");
11624     }
11625 }
11626 
UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,uint64_t userId)11627 void SceneSessionManager::UpdateConstrainedModalUIExtInfo(std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData,
11628     uint64_t userId)
11629 {
11630     if (currentUserId_ != static_cast<int32_t>(userId)) {
11631         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userId:%{public}" PRIu64,
11632             currentUserId_.load(), userId);
11633         return;
11634     }
11635     if (constrainedModalUIExtData == nullptr) {
11636         TLOGE(WmsLogTag::WMS_UIEXT, "invalid constrainedModalUIExtData");
11637         return;
11638     }
11639     auto constrainedModalUIExtInfoMap = constrainedModalUIExtData->GetSecData();
11640     auto task = [constrainedModalUIExtInfoMap]()-> WSError {
11641         SceneInputManager::GetInstance().UpdateConstrainedModalUIExtInfo(constrainedModalUIExtInfoMap);
11642         return WSError::WS_OK;
11643     };
11644     taskScheduler_->PostAsyncTask(task, "UpdateConstrainedModalUIExtInfo");
11645 }
11646 
RegisterConstrainedModalUIExtInfoListener()11647 void SceneSessionManager::RegisterConstrainedModalUIExtInfoListener()
11648 {
11649     auto callBack = [this](std::shared_ptr<RSUIExtensionData> constrainedModalUIExtData, uint64_t userid) {
11650         this->UpdateConstrainedModalUIExtInfo(constrainedModalUIExtData, userid);
11651     };
11652     TLOGI(WmsLogTag::WMS_EVENT, "in");
11653     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack, true) != WM_OK) {
11654         TLOGE(WmsLogTag::WMS_EVENT, "failed");
11655     }
11656 }
11657 
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)11658 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
11659     const AppForceLandscapeConfig& config)
11660 {
11661     if (bundleName.empty()) {
11662         TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
11663         return WSError::WS_ERROR_NULLPTR;
11664     }
11665     std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11666     appForceLandscapeMap_[bundleName] = config;
11667     TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
11668         bundleName.c_str(), config.mode_, config.homePage_.c_str());
11669     return WSError::WS_OK;
11670 }
11671 
GetAppForceLandscapeConfig(const std::string & bundleName)11672 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
11673 {
11674     if (bundleName.empty()) {
11675         return {};
11676     }
11677     std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11678     if (appForceLandscapeMap_.empty() ||
11679         appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
11680         TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
11681         return {};
11682     }
11683     return appForceLandscapeMap_[bundleName];
11684 }
11685 
TerminateSessionByPersistentId(int32_t persistentId)11686 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
11687 {
11688     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
11689         TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
11690         return WMError::WM_ERROR_INVALID_PERMISSION;
11691     }
11692     if (!SessionPermission::IsSystemAppCall()) {
11693         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
11694         return WMError::WM_ERROR_NOT_SYSTEM_APP;
11695     }
11696     auto sceneSession = GetSceneSession(persistentId);
11697     if (sceneSession == nullptr) {
11698         TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
11699         return WMError::WM_ERROR_INVALID_PARAM;
11700     }
11701     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11702         TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11703         return WMError::WM_ERROR_INVALID_PARAM;
11704     }
11705     sceneSession->Clear(true);
11706     TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
11707     return WMError::WM_OK;
11708 }
11709 
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)11710 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
11711 {
11712     rootSceneProcessBackEventFunc_ = processBackEventFunc;
11713     TLOGI(WmsLogTag::WMS_EVENT, "called");
11714 }
11715 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)11716 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
11717     const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
11718 {
11719     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11720         TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
11721         return WMError::WM_ERROR_INVALID_PERMISSION;
11722     }
11723 
11724     surfaceNodeIds.clear();
11725     TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
11726     for (auto persistentId : persistentIds) {
11727         TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
11728         auto sceneSession = GetSceneSession(persistentId);
11729         if (sceneSession == nullptr) {
11730             continue;
11731         }
11732         auto callingPid = sceneSession->GetCallingPid();
11733         auto surfaceNode = sceneSession->GetSurfaceNode();
11734         if (surfaceNode != nullptr && callingPid == pid) {
11735             surfaceNodeIds.push_back(surfaceNode->GetId());
11736             auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
11737             if (leashWinSurfaceNode != nullptr) {
11738                 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
11739                 surfaceNodeIds.push_back(persistentId);
11740             }
11741         }
11742     }
11743 
11744     return WMError::WM_OK;
11745 }
11746 
ReleaseForegroundSessionScreenLock()11747 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
11748 {
11749     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11750         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11751         return WMError::WM_ERROR_INVALID_PERMISSION;
11752     }
11753 #ifdef POWER_MANAGER_ENABLE
11754     auto task = [this] {
11755         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11756         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11757             if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
11758                 continue;
11759             }
11760             auto res = sceneSession->keepScreenLock_->UnLock();
11761             if (res != ERR_OK) {
11762                 TLOGNE(WmsLogTag::DEFAULT,
11763                     "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
11764                     persistentId, sceneSession->GetWindowName().c_str(), res);
11765                 return WMError::WM_ERROR_INVALID_OPERATION;
11766             }
11767             TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
11768                 persistentId, sceneSession->GetWindowName().c_str());
11769         }
11770         return WMError::WM_OK;
11771     };
11772     return taskScheduler_->PostSyncTask(task, __func__);
11773 #else
11774     TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
11775     return WMError::WM_OK;
11776 #endif
11777 }
11778 
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)11779 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
11780 {
11781     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
11782     auto task = [this, func] {
11783         closeTargetFloatWindowFunc_ = func;
11784     };
11785     taskScheduler_->PostTask(task, __func__);
11786 }
11787 
CloseTargetFloatWindow(const std::string & bundleName)11788 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
11789 {
11790     if (!SessionPermission::IsSystemServiceCalling(false)) {
11791         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
11792         return WMError::WM_ERROR_INVALID_PERMISSION;
11793     }
11794     auto task = [this, bundleName] {
11795         if (closeTargetFloatWindowFunc_) {
11796             TLOGNI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
11797             closeTargetFloatWindowFunc_(bundleName);
11798         }
11799     };
11800     taskScheduler_->PostTask(task, __func__);
11801     return WMError::WM_OK;
11802 }
11803 
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)11804 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
11805 {
11806     SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
11807 }
11808 
CloseTargetPiPWindow(const std::string & bundleName)11809 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
11810 {
11811     if (!SessionPermission::IsSystemServiceCalling(false)) {
11812         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11813         return WMError::WM_ERROR_INVALID_PERMISSION;
11814     }
11815     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11816     for (const auto& iter : sceneSessionMap_) {
11817         auto& session = iter.second;
11818         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
11819             session->GetSessionInfo().bundleName_ == bundleName) {
11820             session->NotifyCloseExistPipWindow();
11821             break;
11822         }
11823     }
11824     return WMError::WM_OK;
11825 }
11826 
GetCurrentPiPWindowInfo(std::string & bundleName)11827 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
11828 {
11829     if (!SessionPermission::IsSystemServiceCalling(false)) {
11830         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11831         return WMError::WM_ERROR_INVALID_PERMISSION;
11832     }
11833     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11834     for (const auto& iter : sceneSessionMap_) {
11835         auto& session = iter.second;
11836         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
11837             bundleName = session->GetSessionInfo().bundleName_;
11838             return WMError::WM_OK;
11839         }
11840     }
11841     TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
11842     return WMError::WM_OK;
11843 }
11844 
UpdateDarkColorModeToRS()11845 void SceneSessionManager::UpdateDarkColorModeToRS()
11846 {
11847     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
11848     if (appContext == nullptr) {
11849         TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
11850         return;
11851     }
11852     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
11853     if (config == nullptr) {
11854         TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
11855         return;
11856     }
11857     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
11858     bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
11859     bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
11860     TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d",
11861         colorMode.c_str(), ret);
11862 }
11863 
IsPcWindow(bool & isPcWindow)11864 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
11865 {
11866     isPcWindow = (systemConfig_.uiType_ == UI_TYPE_PC);
11867     return WMError::WM_OK;
11868 }
11869 
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)11870 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
11871 {
11872     isPcOrPadFreeMultiWindowMode = (systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.freeMultiWindowEnable_);
11873     return WMError::WM_OK;
11874 }
11875 
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)11876 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
11877     std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
11878 {
11879     if (!SessionPermission::IsSystemCalling()) {
11880         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11881         return WMError::WM_ERROR_INVALID_PERMISSION;
11882     }
11883 
11884     auto task = [this, windowIds, &windowDisplayIdMap] {
11885         for (const uint64_t windowId : windowIds) {
11886             sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
11887             if (session == nullptr) {
11888                 continue;
11889             }
11890             sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
11891             if (sessionProperty == nullptr) {
11892                 continue;
11893             }
11894 			DisplayId displayId = sessionProperty->GetDisplayId();
11895             TLOGNI(WmsLogTag::DEFAULT, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
11896                 windowId, displayId);
11897             windowDisplayIdMap.insert({windowId, displayId});
11898         }
11899         return WMError::WM_OK;
11900     };
11901     return taskScheduler_->PostSyncTask(task, __func__);
11902 }
11903 
IsLastFrameLayoutFinished(bool & isLayoutFinished)11904 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
11905 {
11906     if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
11907         TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
11908         return WSError::WS_ERROR_NULLPTR;
11909     }
11910     isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
11911     return WSError::WS_OK;
11912 }
11913 
IsWindowRectAutoSave(const std::string & key,bool & enabled)11914 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled)
11915 {
11916     std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11917     if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11918         enabled = iter->second;
11919     } else {
11920         enabled = false;
11921     }
11922     return WMError::WM_OK;
11923 }
11924 
SetIsWindowRectAutoSave(const std::string & key,bool enabled)11925 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled)
11926 {
11927     std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11928     if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11929         if (!enabled) {
11930             isWindowRectAutoSaveMap_.erase(key);
11931         } else {
11932             iter->second = enabled;
11933         }
11934     } else {
11935         if (enabled) {
11936             isWindowRectAutoSaveMap_.insert({key, enabled});
11937         }
11938     }
11939 }
11940 
RemoveAppInfo(const std::string & bundleName)11941 void SceneSessionManager::RemoveAppInfo(const std::string& bundleName)
11942 {
11943     AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
11944 }
11945 
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)11946 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
11947 {
11948     if (!SessionPermission::IsSystemServiceCalling()) {
11949         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11950         return WMError::WM_ERROR_INVALID_PERMISSION;
11951     }
11952     const char* const where = __func__;
11953     auto task = [this, persistentId, &hostWindowId, where]() {
11954         hostWindowId = INVALID_WINDOW_ID;
11955         sptr<Session> session = GetSceneSession(persistentId);
11956         while (session && SessionHelper::IsSubWindow(session->GetWindowType()))
11957         {
11958             session = session->GetParentSession();
11959         }
11960         if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
11961             hostWindowId = session->GetPersistentId();
11962         }
11963         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
11964             where, persistentId, hostWindowId);
11965         return WMError::WM_OK;
11966     };
11967     return taskScheduler_->PostSyncTask(task, where);
11968 }
11969 
MinimizeMainSession(const std::string & bundleName,int32_t appIndex,int32_t userId)11970 WMError SceneSessionManager::MinimizeMainSession(const std::string& bundleName, int32_t appIndex, int32_t userId)
11971 {
11972     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
11973         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
11974         return WMError::WM_ERROR_INVALID_PERMISSION;
11975     }
11976     if ((currentUserId_ != userId && currentUserId_ != DEFAULT_USERID) ||
11977         (currentUserId_ == DEFAULT_USERID && userId != GetUserIdByUid(getuid()))) {
11978         TLOGW(WmsLogTag::WMS_LIFE, "currentUserId:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
11979             currentUserId_.load(), userId, GetUserIdByUid(getuid()));
11980         return WMError::WM_ERROR_INVALID_OPERATION;
11981     }
11982     const char* const where = __func__;
11983     taskScheduler_->PostAsyncTask([this, bundleName, appIndex, where] {
11984         std::vector<sptr<SceneSession>> mainSessions;
11985         GetMainSessionByBundleNameAndAppIndex(bundleName, appIndex, mainSessions);
11986         if (mainSessions.empty()) {
11987             TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, not found any main session", where);
11988             return;
11989         }
11990         for (const auto& session : mainSessions) {
11991             session->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
11992             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, id:%{public}d.", where, session->GetPersistentId());
11993         }
11994     }, __func__);
11995     return WMError::WM_OK;
11996 }
11997 
ShiftAppWindowPointerEvent(int32_t sourcePersistentId,int32_t targetPersistentId)11998 WMError SceneSessionManager::ShiftAppWindowPointerEvent(int32_t sourcePersistentId, int32_t targetPersistentId)
11999 {
12000     TLOGD(WmsLogTag::WMS_PC, "sourcePersistentId %{public}d targetPersistentId %{public}d",
12001     sourcePersistentId, targetPersistentId);
12002     if (!(systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.freeMultiWindowEnable_)) {
12003         return WMError::WM_ERROR_DEVICE_NOT_SUPPORT;
12004     }
12005     if (sourcePersistentId == targetPersistentId) {
12006         return WMError::WM_ERROR_INVALID_CALLING;
12007     }
12008     sptr<SceneSession> sourceSession = GetSceneSession(sourcePersistentId);
12009     if (sourceSession == nullptr) {
12010         TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is nullptr", sourcePersistentId);
12011         return WMError::WM_ERROR_INVALID_SESSION;
12012     }
12013     if (!WindowHelper::IsAppWindow(sourceSession->GetWindowType())) {
12014         TLOGE(WmsLogTag::WMS_PC, "sourceSession %{public}d is not app window", sourcePersistentId);
12015         return WMError::WM_ERROR_INVALID_CALLING;
12016     }
12017     sptr<SceneSession> targetSession = GetSceneSession(targetPersistentId);
12018     if (targetSession == nullptr) {
12019         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is nullptr", targetPersistentId);
12020         return WMError::WM_ERROR_INVALID_SESSION;
12021     }
12022     if (!WindowHelper::IsAppWindow(targetSession->GetWindowType())) {
12023         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not app window", targetPersistentId);
12024         return WMError::WM_ERROR_INVALID_CALLING;
12025     }
12026     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
12027         TLOGE(WmsLogTag::WMS_PC, "verify bundle failed, source name is %{public}s but target name is %{public}s)",
12028         sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
12029         return WMError::WM_ERROR_INVALID_CALLING;
12030     }
12031     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
12032         TLOGE(WmsLogTag::WMS_PC, "targetSession %{public}d is not same bundle as calling", targetPersistentId);
12033         return WMError::WM_ERROR_INVALID_CALLING;
12034     }
12035     int32_t callingPid = IPCSkeleton::GetCallingPid();
12036     if (callingPid != targetSession->GetCallingPid()) {
12037         TLOGE(WmsLogTag::WMS_PC, "permission denied, not call by the same process");
12038         return WMError::WM_ERROR_INVALID_CALLING;
12039     }
12040     return ShiftAppWindowPointerEventInner(sourcePersistentId, targetPersistentId,
12041         targetSession->GetSessionProperty()->GetDisplayId());
12042 }
12043 
ShiftAppWindowPointerEventInner(int32_t sourceWindowId,int32_t targetWindowId,DisplayId targetDisplayId)12044 WMError SceneSessionManager::ShiftAppWindowPointerEventInner(
12045     int32_t sourceWindowId, int32_t targetWindowId, DisplayId targetDisplayId)
12046 {
12047     return taskScheduler_->PostSyncTask([sourceWindowId, targetWindowId, targetDisplayId] {
12048         auto display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
12049         float vpr = 1.5f; // 1.5f: default virtual pixel ratio
12050         if (display) {
12051             vpr = display->GetVirtualPixelRatio();
12052         }
12053         int32_t outside = static_cast<int32_t>(HOTZONE_TOUCH * vpr * 2); // double touch hotzone
12054         MMI::ShiftWindowParam param;
12055         param.sourceWindowId = sourceWindowId;
12056         param.targetWindowId = targetWindowId;
12057         param.x = -outside;
12058         param.y = -outside;
12059         int ret = MMI::InputManager::GetInstance()->ShiftAppPointerEvent(param, true);
12060         TLOGNI(WmsLogTag::WMS_PC, "sourceWindowId %{public}d targetWindowId %{public}d vpr %{public}f ret %{public}d",
12061             param.sourceWindowId, param.targetWindowId, vpr, ret);
12062         return ret == 0 ? WMError::WM_OK : WMError::WM_ERROR_INVALID_CALLING;
12063     }, __func__);
12064 }
12065 
HasFloatingWindowForeground(const sptr<IRemoteObject> & abilityToken,bool & hasOrNot)12066 WMError SceneSessionManager::HasFloatingWindowForeground(const sptr<IRemoteObject>& abilityToken, bool& hasOrNot)
12067 {
12068     if (!abilityToken) {
12069         TLOGE(WmsLogTag::WMS_SYSTEM, "AbilityToken is null");
12070         return WMError::WM_ERROR_NULLPTR;
12071     }
12072     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
12073         TLOGE(WmsLogTag::WMS_SYSTEM, "Permission denied, only for SA");
12074         return WMError::WM_ERROR_INVALID_PERMISSION;
12075     }
12076 
12077     return taskScheduler_->PostSyncTask([this, &abilityToken, &hasOrNot, where = __func__] {
12078         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
12079         for (const auto& [_, session] : sceneSessionMap_) {
12080             if (session && session->GetAbilityToken() == abilityToken &&
12081                 session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT && session->IsSessionForeground()) {
12082                 TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s found", where);
12083                 hasOrNot = true;
12084                 return WMError::WM_OK;
12085             }
12086         }
12087         TLOGNI(WmsLogTag::WMS_SYSTEM, "%{public}s not found", where);
12088         hasOrNot = false;
12089         return WMError::WM_OK;
12090     }, __func__);
12091 }
12092 
LockSessionByAbilityInfo(const AbilityInfoBase & abilityInfo,bool isLock)12093 WMError SceneSessionManager::LockSessionByAbilityInfo(const AbilityInfoBase& abilityInfo, bool isLock)
12094 {
12095     if (!SessionPermission::IsSystemAppCall() && !SessionPermission::IsSACalling()) {
12096         TLOGE(WmsLogTag::WMS_LIFE, "The caller is neither a system app nor an SA.");
12097         return WMError::WM_ERROR_INVALID_PERMISSION;
12098     }
12099     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
12100         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
12101         return WMError::WM_ERROR_INVALID_PERMISSION;
12102     }
12103     TLOGI(WmsLogTag::WMS_LIFE,
12104         "bundleName:%{public}s moduleName:%{public}s abilityName:%{public}s appIndex:%{public}d isLock:%{public}d",
12105         abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.abilityName.c_str(),
12106         abilityInfo.appIndex, isLock);
12107     if (!abilityInfo.IsValid()) {
12108         TLOGE(WmsLogTag::WMS_LIFE, "abilityInfo not valid");
12109         return WMError::WM_ERROR_INVALID_PARAM;
12110     }
12111     taskScheduler_->PostAsyncTask([this, abilityInfo, isLock, where = __func__] {
12112         std::vector<sptr<SceneSession>> mainSessions;
12113         GetMainSessionByAbilityInfo(abilityInfo, mainSessions);
12114         if (!mainSessions.empty()) {
12115             for (const auto& mainSession : mainSessions) {
12116                 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, set isLocked %{public}d, persistentId:%{public}d",
12117                     where, isLock, mainSession->GetPersistentId());
12118                 mainSession->NotifySessionLockStateChange(isLock);
12119             }
12120             if (isLock) {
12121                 return;
12122             }
12123         }
12124         if (isLock) {
12125             if (sessionLockedStateCacheSet_.size() > MAX_LOCK_STATUS_CACHE_SIZE) {
12126                 auto iter = sessionLockedStateCacheSet_.begin();
12127                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s, reach max erase begin:%{public}s", where, (*iter).c_str());
12128                 sessionLockedStateCacheSet_.erase(iter);
12129             }
12130             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s, update isLockedState into cache set", where);
12131             sessionLockedStateCacheSet_.insert(abilityInfo.ToKeyString());
12132         } else {
12133             sessionLockedStateCacheSet_.erase(abilityInfo.ToKeyString());
12134         }
12135     }, __func__);
12136     return WMError::WM_OK;
12137 }
12138 } // namespace OHOS::Rosen