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 
30 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
31 #include <display_power_mgr_client.h>
32 #endif
33 
34 #ifdef POWER_MANAGER_ENABLE
35 #include <power_mgr_client.h>
36 #endif
37 
38 #ifdef RES_SCHED_ENABLE
39 #include "res_type.h"
40 #include "res_sched_client.h"
41 #endif
42 #include "scene_system_ability_listener.h"
43 
44 #include "anr_manager.h"
45 #include "color_parser.h"
46 #include "common/include/session_permission.h"
47 #include "display_manager.h"
48 #include "scene_input_manager.h"
49 #include "session/host/include/main_session.h"
50 #include "session/host/include/scb_system_session.h"
51 #include "session/host/include/scene_persistent_storage.h"
52 #include "session/host/include/session_utils.h"
53 #include "session/host/include/sub_session.h"
54 #include "session_helper.h"
55 #include "window_helper.h"
56 #include "screen_session_manager/include/screen_session_manager_client.h"
57 #include "singleton_container.h"
58 #include "xcollie/watchdog.h"
59 #include "session_manager_agent_controller.h"
60 #include "distributed_client.h"
61 #include "softbus_bus_center.h"
62 #include "perform_reporter.h"
63 #include "anr_manager.h"
64 #include "dms_reporter.h"
65 #include "res_sched_client.h"
66 #include "anomaly_detection.h"
67 #include "session/host/include/ability_info_manager.h"
68 
69 #ifdef MEMMGR_WINDOW_ENABLE
70 #include "mem_mgr_client.h"
71 #include "mem_mgr_window_info.h"
72 #endif
73 
74 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
75 #include "sec_comp_enhance_kit.h"
76 #endif
77 
78 #ifdef IMF_ENABLE
79 #include <input_method_controller.h>
80 #endif // IMF_ENABLE
81 
82 namespace OHOS::Rosen {
83 namespace {
84 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
85 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
86 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
87 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
88 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
89 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
90 
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 STATUS_BAR_AVOID_AREA = 0;
114 const std::string ARG_DUMP_ALL = "-a";
115 const std::string ARG_DUMP_WINDOW = "-w";
116 const std::string ARG_DUMP_SCREEN = "-s";
117 const std::string ARG_DUMP_DISPLAY = "-d";
118 const std::string ARG_DUMP_PIPLINE = "-p";
119 const std::string ARG_DUMP_SCB = "-b";
120 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
121 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
122 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
123 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
124 
125 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
126     {"unspecified",                         OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
127     {"landscape",                           OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
128     {"portrait",                            OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
129     {"follow_recent",                       OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
130     {"landscape_inverted",                  OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
131     {"portrait_inverted",                   OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
132     {"auto_rotation",                       OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
133     {"auto_rotation_landscape",             OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
134     {"auto_rotation_portrait",              OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
135     {"auto_rotation_restricted",            OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
136     {"auto_rotation_landscape_restricted",  OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
137     {"auto_rotation_portrait_restricted",   OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
138     {"locked",                              OHOS::AppExecFwk::DisplayOrientation::LOCKED},
139     {"auto_rotation_unspecified",           OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
140     {"follow_desktop",                      OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
141 };
142 
143 static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
144 
145 static std::shared_ptr<ScbDumpSubscriber> g_scbSubscriber(nullptr);
146 
GetCurrentTime()147 std::string GetCurrentTime()
148 {
149     struct timespec tn;
150     clock_gettime(CLOCK_REALTIME, &tn);
151     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
152         static_cast<uint64_t>(tn.tv_nsec);
153     return std::to_string(uTime);
154 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)155 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
156 {
157     return a.first < b.first;
158 }
159 
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)160 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
161 {
162     if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
163         value = (*item.intsValue_)[0];
164         return true;
165     }
166     return false;
167 }
168 
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)169 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
170 {
171     auto& metadata = abilityInfo->metadata;
172     for (const auto& item : metadata) {
173         if (item.name == "enable.remove.starting.window") {
174             return item.value == "true";
175         }
176     }
177     return false;
178 }
179 
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)180 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
181     AppExecFwk::ExtensionAbilityType extensionAbilityType)
182 {
183     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
184           element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
185     static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
186         AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
187     };
188     static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
189         std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
190         std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
191         std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
192         std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
193         std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
194         std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
195         std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
196         std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
197         std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
198         std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
199         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
200         std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
201         std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
202         std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
203         std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
204         std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
205         std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
206         std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
207         std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
208         std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
209     };
210 
211     if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
212         TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: extensionAbilityType in white list");
213         return true;
214     }
215 
216     auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
217         auto& [bundleName, abilityName, _] = item;
218         return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
219     });
220     if (it != elementNameWhitelist.end()) {
221         return true;
222     }
223 
224     TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
225     return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
226         PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
227 }
228 
229 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
230 public:
231     BundleStatusCallback() = default;
232     virtual ~BundleStatusCallback() = default;
233 
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)234     void OnBundleStateChanged(const uint8_t installType,
235         const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
236 
OnBundleAdded(const std::string & bundleName,const int userId)237     void OnBundleAdded(const std::string& bundleName, const int userId) override
238     {
239         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
240     }
241 
OnBundleUpdated(const std::string & bundleName,const int userId)242     void OnBundleUpdated(const std::string& bundleName, const int userId) override
243     {
244         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
245     }
246 
OnBundleRemoved(const std::string & bundleName,const int userId)247     void OnBundleRemoved(const std::string& bundleName, const int userId) override
248     {
249         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
250     }
251 };
252 } // namespace
253 
CreateInstance()254 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
255 {
256     sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
257     sessionManager->Init();
258     return sessionManager;
259 }
260 
GetInstance()261 SceneSessionManager& SceneSessionManager::GetInstance()
262 {
263     static sptr<SceneSessionManager> instance = CreateInstance();
264     return *instance;
265 }
266 
SceneSessionManager()267 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
268 {
269     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
270     currentUserId_ = DEFAULT_USERID;
271     launcherService_ = new AppExecFwk::LauncherService();
272     if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
273         WLOGFE("Failed to register bundle status callback.");
274     }
275     ScbDumpSubscriber::Subscribe(g_scbSubscriber);
276 }
277 
~SceneSessionManager()278 SceneSessionManager::~SceneSessionManager()
279 {
280     ScbDumpSubscriber::UnSubscribe(g_scbSubscriber);
281 }
282 
Init()283 void SceneSessionManager::Init()
284 {
285     auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
286     bool isScbCoreEnabled = (deviceType == UI_TYPE_PHONE || deviceType == "tablet") &&
287         system::GetParameter("persist.window.scbcore.enable", "1") == "1";
288     Session::SetScbCoreEnabled(isScbCoreEnabled);
289 
290     constexpr uint64_t interval = 5 * 1000; // 5 second
291     if (HiviewDFX::Watchdog::GetInstance().AddThread(
292         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
293         WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
294     }
295 
296     bundleMgr_ = GetBundleManager();
297     LoadWindowSceneXml();
298     sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
299     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
300     InitPrepareTerminateConfig();
301     // create handler for inner command at server
302     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
303     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
304     if (eventHandler_ == nullptr) {
305         WLOGFE("Invalid eventHander");
306         return ;
307     }
308     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
309     if (ret != 0) {
310         WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
311     }
312 
313     listenerController_ = std::make_shared<SessionListenerController>();
314     listenerController_->Init();
315     scbSessionHandler_ = new ScbSessionHandler();
316     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
317     StartWindowInfoReportLoop();
318     WLOGI("SSM init success.");
319     RegisterAppListener();
320     openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
321     isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1")  == "1";
322     SceneInputManager::GetInstance().Init();
323 
324     // MMI window state error check
325     int32_t retCode = MMI::InputManager::GetInstance()->
326         RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
327         this->NotifyWindowStateErrorFromMMI(pid, persistentId);
328     });
329     TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
330 
331     AbilityInfoManager::GetInstance().Init(bundleMgr_);
332     AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
333     UpdateDarkColorModeToRS();
334 }
335 
InitScheduleUtils()336 void SceneSessionManager::InitScheduleUtils()
337 {
338 #ifdef RES_SCHED_ENABLE
339     SCBThreadInfo threadInfo = {
340         .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
341         .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
342     };
343     std::unordered_map<std::string, std::string> payload {
344         { "pid", threadInfo.scbPid_ },
345         { "tid", threadInfo.scbTid_ },
346         { "uid", threadInfo.scbUid_ },
347         { "bundleName", threadInfo.scbBundleName_ },
348     };
349     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
350     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
351     auto task = [threadInfo = std::move(threadInfo)]() mutable {
352         threadInfo.ssmThreadName_ = "OS_SceneSession";
353         threadInfo.ssmTid_ = std::to_string(gettid());
354         const int32_t userInteraction = 2;
355         std::unordered_map<std::string, std::string> payload{
356             { "pid", threadInfo.scbPid_ },
357             { "tid", threadInfo.ssmTid_ },
358             { "uid", threadInfo.scbUid_ },
359             { "extType", "10002" },
360             { "cgroupPrio", "1" },
361             { "isSa", "0" },
362             { "threadName", threadInfo.ssmThreadName_ }
363         };
364         uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
365         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
366         TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
367         sptr<ISystemAbilityManager> systemAbilityManager =
368             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
369         if (!systemAbilityManager) {
370             TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
371             return;
372         }
373         auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
374         int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
375         if (ret != ERR_OK) {
376             TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
377         }
378     };
379     taskScheduler_->PostAsyncTask(task, "changeQosTask");
380 #endif
381 }
382 
RegisterAppListener()383 void SceneSessionManager::RegisterAppListener()
384 {
385     appAnrListener_ = new (std::nothrow) AppAnrListener();
386     auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
387     if (appMgrClient_ == nullptr) {
388         WLOGFE("appMgrClient_ is nullptr.");
389     } else if (appAnrListener_ == nullptr) {
390         WLOGFE("appAnrListener_ is nullptr.");
391     } else {
392         auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
393         if (flag != ERR_OK) {
394             WLOGFE("Register app debug listener failed.");
395         } else {
396             WLOGFI("Register app debug listener success.");
397         }
398     }
399 }
400 
LoadWindowSceneXml()401 void SceneSessionManager::LoadWindowSceneXml()
402 {
403     if (WindowSceneConfig::LoadConfigXml()) {
404         if (WindowSceneConfig::GetConfig().IsMap()) {
405             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
406         }
407         ConfigWindowSceneXml();
408     } else {
409         WLOGFE("Load window scene xml failed");
410     }
411     ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
412         appWindowSceneConfig_.keyboardAnimationOut_);
413 }
414 
InitPrepareTerminateConfig()415 void SceneSessionManager::InitPrepareTerminateConfig()
416 {
417     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
418     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
419         PREPARE_TERMINATE_ENABLE_SIZE);
420     WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
421     if (retSysParam > 0 && !std::strcmp(value, "true")) {
422         isPrepareTerminateEnable_ = true;
423     }
424 }
425 
ConfigWindowSceneXml()426 void SceneSessionManager::ConfigWindowSceneXml()
427 {
428     const auto& config = WindowSceneConfig::GetConfig();
429     WindowSceneConfig::ConfigItem item = config["windowEffect"];
430     if (item.IsMap()) {
431         ConfigWindowEffect(item);
432     }
433 
434     item = config["decor"];
435     if (item.IsMap()) {
436         ConfigDecor(item);
437     }
438 
439     item = config["backgroundswitch"];
440     if (item.IsInts()) {
441         auto numbers = *item.intsValue_;
442         if (numbers.size() == 1 && numbers[0] == 1) {
443             systemConfig_.backgroundswitch = true;
444         }
445     }
446     WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
447 
448     item = config["defaultWindowMode"];
449     if (item.IsInts()) {
450         auto numbers = *item.intsValue_;
451         if (numbers.size() == 1 &&
452             (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
453              numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
454             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
455         }
456     }
457 
458     item = config["defaultMaximizeMode"];
459     if (item.IsInts()) {
460         auto numbers = *item.intsValue_;
461         if (numbers.size() == 1 &&
462             (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
463             numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
464             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
465         }
466     }
467 
468     item = config["keyboardAnimation"];
469     if (item.IsMap()) {
470         ConfigKeyboardAnimation(item);
471     }
472 
473     item = config["maxFloatingWindowSize"];
474     if (item.IsInts()) {
475         auto numbers = *item.intsValue_;
476         if (numbers.size() == 1) {
477             systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
478         }
479     }
480 
481     item = config["windowAnimation"];
482     if (item.IsMap()) {
483         ConfigWindowAnimation(item);
484     }
485 
486     item = config["startWindowTransitionAnimation"];
487     if (item.IsMap()) {
488         ConfigStartingWindowAnimation(item);
489     }
490     item = config["maxMidSceneNum"];
491     if (item.IsInts()) {
492         auto numbers = *item.intsValue_;
493         if (numbers.size() == 1) {
494             systemConfig_.maxMidSceneNum_ = static_cast<uint32_t>(numbers[0]);
495         }
496     }
497     ConfigFreeMultiWindow();
498     ConfigWindowSizeLimits();
499     ConfigSnapshotScale();
500     ConfigWindowSceneXml(config);
501 }
502 
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)503 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
504 {
505     WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
506     if (item.IsMap()) {
507         ConfigSystemUIStatusBar(item);
508     }
509     item = config["uiType"];
510     if (item.IsString()) {
511         systemConfig_.uiType_ = item.stringValue_;
512         appWindowSceneConfig_.uiType_ = item.stringValue_;
513     }
514     item = config["backgroundScreenLock"].GetProp("enable");
515     if (item.IsBool()) {
516         appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
517     }
518     item = config["rotationMode"];
519     if (item.IsString()) {
520         appWindowSceneConfig_.rotationMode_ = item.stringValue_;
521     }
522     item = config["immersive"];
523     if (item.IsMap()) {
524         ConfigWindowImmersive(item);
525     }
526     item = config["supportTypeFloatWindow"].GetProp("enable");
527     if (item.IsBool()) {
528         systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
529     }
530 }
531 
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)532 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
533 {
534     AppWindowSceneConfig config;
535     WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
536     if (item.IsMap()) {
537         if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
538             appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
539                 config.windowImmersive_.desktopStatusBarConfig_;
540         }
541     }
542     item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
543     if (item.IsMap()) {
544         if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
545             appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
546                 config.windowImmersive_.upDownStatusBarConfig_;
547         }
548     }
549     item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
550     if (item.IsMap()) {
551         if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
552             appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
553                 config.windowImmersive_.leftRightStatusBarConfig_;
554         }
555     }
556 }
557 
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)558 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
559     StatusBarConfig& statusBarConfig)
560 {
561     WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
562     if (item.IsBool()) {
563         statusBarConfig.showHide_ = item.boolValue_;
564     }
565     item = config["contentColor"];
566     if (item.IsString()) {
567         statusBarConfig.contentColor_ = item.stringValue_;
568     }
569     item = config["backgroundColor"];
570     if (item.IsString()) {
571         statusBarConfig.backgroundColor_ = item.stringValue_;
572     }
573     return true;
574 }
575 
ConfigFreeMultiWindow()576 void SceneSessionManager::ConfigFreeMultiWindow()
577 {
578     const auto& config = WindowSceneConfig::GetConfig();
579     WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
580     if (freeMultiWindowConfig.IsMap()) {
581         auto supportItem = freeMultiWindowConfig.GetProp("enable");
582         if (supportItem.IsBool()) {
583             systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
584         }
585         auto item = freeMultiWindowConfig["decor"];
586         if (item.IsMap()) {
587             ConfigDecor(item, false);
588         }
589         int32_t param = -1;
590         item = freeMultiWindowConfig["defaultWindowMode"];
591         if (GetSingleIntItem(item, param) &&
592             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
593             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
594             systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
595                 static_cast<WindowMode>(static_cast<uint32_t>(param));
596         }
597         item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
598         if (GetSingleIntItem(item, param) && (param > 0)) {
599             systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
600         }
601     }
602 }
603 
LoadFreeMultiWindowConfig(bool enable)604 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
605 {
606     FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
607     if (enable) {
608         systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
609         systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
610         systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
611     } else {
612         const auto& config = WindowSceneConfig::GetConfig();
613         auto item = config["decor"];
614         if (item.IsMap()) {
615             ConfigDecor(item, true);
616         }
617         int32_t param = -1;
618         item = config["defaultWindowMode"];
619         if (GetSingleIntItem(item, param) &&
620             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
621             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
622             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
623         }
624     }
625     systemConfig_.freeMultiWindowEnable_ = enable;
626 }
627 
GetSystemSessionConfig() const628 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
629 {
630     return systemConfig_;
631 }
632 
SwitchFreeMultiWindow(bool enable)633 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
634 {
635     if (!systemConfig_.freeMultiWindowSupport_) {
636         TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
637         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
638     }
639     LoadFreeMultiWindowConfig(enable);
640     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
641     for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
642         auto sceneSession = item->second;
643         if (sceneSession == nullptr) {
644             continue;
645         }
646         auto property = sceneSession->GetSessionProperty();
647         if (property == nullptr) {
648             continue;
649         }
650         bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
651             property->GetExtensionFlag();
652         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
653             sceneSession->SwitchFreeMultiWindow(enable);
654         }
655     }
656     WindowStyleType type = enable ?
657             WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
658     SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
659     return WSError::WS_OK;
660 }
661 
GetFreeMultiWindowEnableState(bool & enable)662 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
663 {
664     enable = systemConfig_.freeMultiWindowEnable_;
665     return WSError::WS_OK;
666 }
667 
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)668 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
669     const ContinueState& continueState)
670 {
671     TLOGI(WmsLogTag::DEFAULT, "Enter");
672     auto task = [this, token, continueState]() {
673         sptr <SceneSession> sceneSession = FindSessionByToken(token);
674         if (sceneSession == nullptr) {
675             TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
676             return WSError::WS_ERROR_INVALID_PARAM;
677         }
678         sceneSession->SetSessionInfoContinueState(continueState);
679         DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
680             static_cast<AAFwk::ContinueState>(continueState));
681         TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
682             sceneSession->GetPersistentId(), continueState);
683         return WSError::WS_OK;
684     };
685     return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
686 }
687 
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)688 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
689 {
690     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
691     if (item.IsBool()) {
692         if (mainConfig) {
693             systemConfig_.isSystemDecorEnable_ = item.boolValue_;
694         } else {
695             systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
696         }
697         bool decorEnable = item.boolValue_;
698         uint32_t support = 0;
699         std::vector<std::string> supportedModes;
700         item = decorConfig["supportedMode"];
701         if (item.IsStrings()) {
702             supportedModes = *item.stringsValue_;
703         }
704         for (auto mode : supportedModes) {
705             if (mode == "fullscreen") {
706                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
707             } else if (mode == "floating") {
708                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
709             } else if (mode == "pip") {
710                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
711             } else if (mode == "split") {
712                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
713                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
714             } else {
715                 WLOGFW("Invalid supporedMode");
716                 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
717                 break;
718             }
719         }
720         if (mainConfig && item.IsStrings()) {
721             systemConfig_.decorWindowModeSupportType_ = support;
722         }
723         if (!mainConfig && item.IsStrings()) {
724             systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
725         }
726     }
727 }
728 
AddAlphaToColor(float alpha,std::string & color)729 static void AddAlphaToColor(float alpha, std::string& color)
730 {
731     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
732         return;
733     }
734 
735     uint32_t alphaValue = 0xFF * alpha;
736     std::stringstream ss;
737     ss << std::hex << alphaValue;
738     std::string strAlpha = ss.str();
739     if (strAlpha.size() == 1) {
740         strAlpha.append(1, '0');
741     }
742 
743     color.insert(1, strAlpha);
744 }
745 
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)746 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
747 {
748     return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
749         (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
750         AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
751 }
752 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)753 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
754 {
755     AppWindowSceneConfig config;
756     // config corner radius
757     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
758     if (item.IsMap()) {
759         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
760             appWindowSceneConfig_ = config;
761         }
762     }
763 
764     // config shadow
765     item = effectConfig["appWindows"]["shadow"]["focused"];
766     if (item.IsMap()) {
767         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
768             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
769         }
770     }
771 
772     item = effectConfig["appWindows"]["shadow"]["unfocused"];
773     if (item.IsMap()) {
774         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
775             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
776         }
777     }
778 
779     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
780     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
781 
782     WLOGFI("Config window effect successfully");
783 }
784 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)785 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
786 {
787     std::map<std::string, float> stringToCornerRadius = {
788         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
789         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
790     };
791 
792     if (item.IsString()) {
793         auto value = item.stringValue_;
794         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
795             out = stringToCornerRadius[value];
796             return true;
797         }
798     }
799     return false;
800 }
801 
SetEnableInputEvent(bool enabled)802 void SceneSessionManager::SetEnableInputEvent(bool enabled)
803 {
804     TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
805     enableInputEvent_ = enabled;
806 }
807 
IsInputEventEnabled()808 bool SceneSessionManager::IsInputEventEnabled()
809 {
810     return enableInputEvent_;
811 }
812 
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)813 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
814 {
815     for (const auto& persistentId : alivePersistentIds_) {
816         auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
817         if (it != recoveredPersistentIds.end()) {
818             continue;
819         }
820         auto sceneSession = GetSceneSession(persistentId);
821         if (sceneSession == nullptr) {
822             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
823             continue;
824         }
825         if (sceneSession->IsRecovered()) {
826             TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
827             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
828             EraseSceneSessionAndMarkDirtyLocked(persistentId);
829         }
830     }
831 }
832 
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)833 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
834 {
835     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
836         recoveredPersistentIds.size(), currentUserId_.load());
837 
838     auto task = [this, recoveredPersistentIds]() {
839         ClearUnrecoveredSessions(recoveredPersistentIds);
840         std::list<AAFwk::SessionInfo> abilitySessionInfos;
841         for (const auto& persistentId : recoveredPersistentIds) {
842             if (failRecoveredPersistentIdSet_.count(persistentId)) {
843                 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
844                 continue;
845             }
846             auto sceneSession = GetSceneSession(persistentId);
847             if (sceneSession == nullptr) {
848                 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
849                 continue;
850             }
851             const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
852             if (!abilitySessionInfo) {
853                 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
854                 continue;
855             }
856             TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
857             abilitySessionInfos.emplace_back(*abilitySessionInfo);
858         }
859         std::vector<int32_t> unrecoverableSessionIds;
860         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
861             abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
862         TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
863             unrecoverableSessionIds.size());
864         for (const auto& sessionId : unrecoverableSessionIds) {
865             auto sceneSession = GetSceneSession(sessionId);
866             if (sceneSession == nullptr) {
867                 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
868                     sessionId);
869                 continue;
870             }
871             const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
872             if (!scnSessionInfo) {
873                 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
874                 continue;
875             }
876             TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
877             sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
878         }
879         removeFailRecoveredSession();
880     };
881     return taskScheduler_->PostAsyncTask(task);
882 }
883 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)884 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
885     WindowShadowConfig& outShadow)
886 {
887     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
888     if (item.IsString()) {
889         auto color = item.stringValue_;
890         uint32_t colorValue;
891         if (!ColorParser::Parse(color, colorValue)) {
892             return false;
893         }
894         outShadow.color_ = color;
895     }
896 
897     item = shadowConfig["offsetX"];
898     if (item.IsFloats()) {
899         auto offsetX = *item.floatsValue_;
900         if (offsetX.size() != 1) {
901             return false;
902         }
903         outShadow.offsetX_ = offsetX[0];
904     }
905 
906     item = shadowConfig["offsetY"];
907     if (item.IsFloats()) {
908         auto offsetY = *item.floatsValue_;
909         if (offsetY.size() != 1) {
910             return false;
911         }
912         outShadow.offsetY_ = offsetY[0];
913     }
914 
915     item = shadowConfig["alpha"];
916     if (item.IsFloats()) {
917         auto alpha = *item.floatsValue_;
918         if (alpha.size() != 1 ||
919             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
920             return false;
921         }
922         outShadow.alpha_ = alpha[0];
923     }
924 
925     item = shadowConfig["radius"];
926     if (item.IsFloats()) {
927         auto radius = *item.floatsValue_;
928         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
929             return false;
930         }
931         outShadow.radius_ = radius[0];
932     }
933 
934     return true;
935 }
936 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)937 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
938     KeyboardSceneAnimationConfig& config)
939 {
940     if (item.IsMap() && item.mapValue_->count("curve")) {
941         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
942         config.curveType_ = curveType;
943         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
944             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
945             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
946             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
947             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
948         }
949     }
950 
951     const WindowSceneConfig::ConfigItem& duration = item["duration"];
952     if (duration.IsInts()) {
953         auto numbers = *duration.intsValue_;
954         if (numbers.size() == 1) {
955             config.duration_ = static_cast<uint32_t>(numbers[0]);
956         }
957     }
958 }
959 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)960 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
961 {
962     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
963     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
964 
965     // config system animation
966     const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
967     systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
968         {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
969         appConfigIn.duration_);
970     const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
971     systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
972         {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
973         appConfigOut.duration_);
974 }
975 
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)976 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
977     KeyboardSceneAnimationConfig& animationOut)
978 {
979     if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
980         TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
981             "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
982             systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
983             systemConfig_.animationOut_.duration_);
984         return;
985     }
986 
987     // default animation curve params
988     constexpr char CURVETYPE[] = "interpolatingSpring";
989     constexpr float IN_CTRLX1 = 0.0f;
990     constexpr float OUT_CTRLX1 = 4.0f;
991     constexpr float CTRLY1 = 1.0f;
992     constexpr float CTRLX2 = 342.0f;
993     constexpr float CTRLY2 = 37.0f;
994     constexpr uint32_t DURATION = 150;
995     std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
996     std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
997 
998     // update system config for client
999     systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1000     systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1001 
1002     // update app config for server
1003     animationIn.curveType_ = CURVETYPE;
1004     animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1005     animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1006     animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1007     animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1008     animationIn.duration_ = DURATION;
1009 
1010     animationOut.curveType_ = CURVETYPE;
1011     animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1012     animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1013     animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1014     animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1015     animationOut.duration_ = DURATION;
1016     TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
1017 }
1018 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1019 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1020 {
1021     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1022     if (item.IsMap() && item.mapValue_->count("curve")) {
1023         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1024         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1025         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1026             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1027             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1028             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1029             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1030         }
1031     }
1032     item = windowAnimationConfig["timing"]["duration"];
1033     if (item.IsInts() && item.intsValue_->size() == 1) {
1034         auto duration = *item.intsValue_;
1035         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1036     }
1037     item = windowAnimationConfig["scale"];
1038     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1039         auto scales = *item.floatsValue_;
1040         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1041         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1042     }
1043     item = windowAnimationConfig["rotation"];
1044     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1045         auto rotations = *item.floatsValue_;
1046         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1047         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1048         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1049         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1050     }
1051     item = windowAnimationConfig["translate"];
1052     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1053         auto translates = *item.floatsValue_;
1054         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1055         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1056     }
1057     item = windowAnimationConfig["opacity"];
1058     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1059         auto opacity = *item.floatsValue_;
1060         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1061     }
1062 }
1063 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1064 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1065 {
1066     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1067     auto item = configItem.GetProp("enable");
1068     if (item.IsBool()) {
1069         config.enabled_ = item.boolValue_;
1070     }
1071     item = configItem["timing"];
1072     if (item.IsMap() && item.mapValue_->count("curve")) {
1073         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1074     }
1075     item = configItem["timing"]["duration"];
1076     if (item.IsInts() && item.intsValue_->size() == 1) {
1077         config.duration_ = (*item.intsValue_)[0];
1078     }
1079     item = configItem["opacityStart"];
1080     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1081         config.opacityStart_ = (*item.floatsValue_)[0];
1082     }
1083     item = configItem["opacityEnd"];
1084     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1085         config.opacityEnd_ = (*item.floatsValue_)[0];
1086     }
1087 }
1088 
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1089 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1090     const WindowSceneConfig::ConfigItem& curveConfig)
1091 {
1092     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1093         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1094     static std::unordered_set<std::string> paramCurveSet = {
1095         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1096 
1097     std::string curveName = "easeOut";
1098     const auto& nameItem = curveConfig.GetProp("name");
1099     if (!nameItem.IsString()) {
1100         return {curveName, {}};
1101     }
1102 
1103     std::string name = nameItem.stringValue_;
1104     std::vector<float> curveParams;
1105 
1106     if (paramCurveSet.find(name) != paramCurveSet.end()) {
1107         curveName = name;
1108         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1109         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1110             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1111                 curveParams.begin());
1112         }
1113     } else {
1114         auto iter = curveSet.find(name);
1115         if (iter != curveSet.end()) {
1116             curveName = name;
1117         }
1118     }
1119 
1120     return {curveName, curveParams};
1121 }
1122 
ConfigWindowSizeLimits()1123 void SceneSessionManager::ConfigWindowSizeLimits()
1124 {
1125     const auto& config = WindowSceneConfig::GetConfig();
1126     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1127     if (item.IsMap()) {
1128         ConfigMainWindowSizeLimits(item);
1129     }
1130 
1131     item = config["subWindowSizeLimits"];
1132     if (item.IsMap()) {
1133         ConfigSubWindowSizeLimits(item);
1134     }
1135 }
1136 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1137 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1138 {
1139     auto item = mainWindowSizeConifg["miniWidth"];
1140     if (item.IsInts()) {
1141         auto numbers = *item.intsValue_;
1142         if (numbers.size() == 1) {
1143             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1144         }
1145     }
1146 
1147     item = mainWindowSizeConifg["miniHeight"];
1148     if (item.IsInts()) {
1149         auto numbers = *item.intsValue_;
1150         if (numbers.size() == 1) {
1151             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1152         }
1153     }
1154 }
1155 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1156 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1157 {
1158     auto item = subWindowSizeConifg["miniWidth"];
1159     if (item.IsInts()) {
1160         auto numbers = *item.intsValue_;
1161         if (numbers.size() == 1) {
1162             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1163         }
1164     }
1165 
1166     item = subWindowSizeConifg["miniHeight"];
1167     if (item.IsInts()) {
1168         auto numbers = *item.intsValue_;
1169         if (numbers.size() == 1) {
1170             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1171         }
1172     }
1173 }
1174 
ConfigSnapshotScale()1175 void SceneSessionManager::ConfigSnapshotScale()
1176 {
1177     const auto& config = WindowSceneConfig::GetConfig();
1178     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1179     if (item.IsFloats()) {
1180         auto snapshotScale = *item.floatsValue_;
1181         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1182             return;
1183         }
1184         snapshotScale_ = snapshotScale[0];
1185     }
1186 }
1187 
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1188 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1189 {
1190     TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1191     WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1192     if (item.IsInts() && item.intsValue_->size() == 1) {
1193         bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1194         appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1195         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1196             appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1197     }
1198 
1199     item = statusBarConfig["immersiveStatusBarBgColor"];
1200     if (item.IsString()) {
1201         auto color = item.stringValue_;
1202         uint32_t colorValue;
1203         if (!ColorParser::Parse(color, colorValue)) {
1204             return;
1205         }
1206         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1207         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1208             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1209     }
1210 
1211     item = statusBarConfig["immersiveStatusBarContentColor"];
1212     if (item.IsString()) {
1213         auto color = item.stringValue_;
1214         uint32_t colorValue;
1215         if (!ColorParser::Parse(color, colorValue)) {
1216             return;
1217         }
1218         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1219         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1220             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1221     }
1222 }
1223 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1224 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1225 {
1226     rootSceneContextWeak_ = contextWeak;
1227 }
1228 
GetRootSceneSession()1229 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1230 {
1231     auto task = [this]() -> sptr<RootSceneSession> {
1232         if (rootSceneSession_ != nullptr) {
1233             return rootSceneSession_;
1234         }
1235         system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1236         rootSceneSession_ = new RootSceneSession();
1237         rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1238         AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1239         return rootSceneSession_;
1240     };
1241 
1242     return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1243 }
1244 
GetRootSessionAvoidSessionRect(AvoidAreaType type)1245 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1246 {
1247     sptr<RootSceneSession> rootSession = GetRootSceneSession();
1248     if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1249         return {};
1250     }
1251     DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1252     std::vector<sptr<SceneSession>> sessionVector;
1253     switch (type) {
1254         case AvoidAreaType::TYPE_SYSTEM: {
1255             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1256             break;
1257         }
1258         case AvoidAreaType::TYPE_KEYBOARD: {
1259             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1260             break;
1261         }
1262         default: {
1263             TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1264             return {};
1265         }
1266     }
1267 
1268     for (auto& session : sessionVector) {
1269         if (!session->IsVisible()) {
1270             continue;
1271         }
1272         const WSRect rect = session->GetSessionRect();
1273         TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1274         return rect;
1275     }
1276     return {};
1277 }
1278 
GetSceneSession(int32_t persistentId)1279 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1280 {
1281     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1282     auto iter = sceneSessionMap_.find(persistentId);
1283     if (iter == sceneSessionMap_.end()) {
1284         WLOGFD("Error found scene session with id: %{public}d", persistentId);
1285         return nullptr;
1286     }
1287     return iter->second;
1288 }
1289 
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1290 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1291     const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1292 {
1293     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1294     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1295         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1296             sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1297             SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1298             mainSessions.push_back(sceneSession);
1299         }
1300     }
1301 }
1302 
GetSceneSessionByName(const ComparedSessionInfo & info)1303 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const ComparedSessionInfo& info)
1304 {
1305     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1306     for (const auto &item : sceneSessionMap_) {
1307         auto sceneSession = item.second;
1308         if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1309             sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1310             sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1311             continue;
1312         }
1313         if (info.isAtomicService_) {
1314             if ((sceneSession->GetSessionInfo().moduleName_.empty() ||
1315                 sceneSession->GetSessionInfo().moduleName_ == info.moduleName_) &&
1316                 (sceneSession->GetSessionInfo().abilityName_.empty() ||
1317                 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_)) {
1318                 return sceneSession;
1319             }
1320         } else if (sceneSession->GetSessionInfo().moduleName_ == info.moduleName_ &&
1321             sceneSession->GetSessionInfo().abilityName_ == info.abilityName_) {
1322             return sceneSession;
1323         }
1324     }
1325     return nullptr;
1326 }
1327 
GetSceneSessionByType(WindowType type)1328 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1329 {
1330     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1331     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1332         if (sceneSession && sceneSession->GetWindowType() == type) {
1333             return sceneSession;
1334         }
1335     }
1336     return nullptr;
1337 }
1338 
GetSceneSessionByBundleName(const std::string & bundleName)1339 sptr<SceneSession> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1340 {
1341     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1342     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1343         if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1344             return sceneSession;
1345         }
1346     }
1347     return nullptr;
1348 }
1349 
GetSceneSessionVectorByType(WindowType type,uint64_t displayId)1350 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(
1351     WindowType type, uint64_t displayId)
1352 {
1353     if (displayId == DISPLAY_ID_INVALID) {
1354         TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1355         return {};
1356     }
1357     std::vector<sptr<SceneSession>> sceneSessionVector;
1358     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1359     for (const auto &item : sceneSessionMap_) {
1360         auto sceneSession = item.second;
1361         if (sceneSession->GetWindowType() == type &&
1362             sceneSession->GetSessionProperty() &&
1363             sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1364             sceneSessionVector.emplace_back(sceneSession);
1365         }
1366     }
1367 
1368     return sceneSessionVector;
1369 }
1370 
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1371 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1372     sptr<WindowSessionProperty> property)
1373 {
1374     if (property == nullptr) {
1375         TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1376         return WSError::WS_ERROR_NULLPTR;
1377     }
1378     if (sceneSession == nullptr) {
1379         TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1380         return WSError::WS_ERROR_NULLPTR;
1381     }
1382     auto parentPersistentId = property->GetParentPersistentId();
1383     sceneSession->SetParentPersistentId(parentPersistentId);
1384     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1385         auto parentSession = GetSceneSession(parentPersistentId);
1386         if (parentSession == nullptr) {
1387             TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1388             return WSError::WS_ERROR_NULLPTR;
1389         }
1390         parentSession->BindDialogSessionTarget(sceneSession);
1391         parentSession->BindDialogToParentSession(sceneSession);
1392         sceneSession->SetParentSession(parentSession);
1393         TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1394             sceneSession->GetPersistentId(), parentPersistentId);
1395     }
1396     return WSError::WS_OK;
1397 }
1398 
CreateSpecificSessionCallback()1399 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1400 {
1401     sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
1402     if (specificCb == nullptr) {
1403         WLOGFE("SpecificSessionCallback is nullptr");
1404         return nullptr;
1405     }
1406     specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1407         return this->RequestSceneSession(sessionInfo, property);
1408     };
1409     specificCb->onDestroy_ = [this](const int32_t persistentId) {
1410         return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1411     };
1412     specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1413         this->ClearDisplayStatusBarTemporarilyFlags();
1414     };
1415     specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1416         this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1417     };
1418     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type, uint64_t displayId) {
1419         return this->GetSceneSessionVectorByType(type, displayId);
1420     };
1421     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1422         this->UpdateAvoidArea(persistentId);
1423     };
1424     specificCb->onUpdateAvoidAreaByType_ = [this](int32_t persistentId, AvoidAreaType type) {
1425         this->UpdateAvoidAreaByType(persistentId, type);
1426     };
1427     specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1428         return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1429     };
1430     specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1431         this->UpdateOccupiedAreaIfNeed(persistentId);
1432     };
1433     specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1434         this->NotifyWindowInfoChange(persistentId, type);
1435     };
1436     specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1437         this->NotifyMMIWindowPidChange(windowId, startMoving);
1438     };
1439     specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1440         this->NotifySessionTouchOutside(persistentId);
1441     };
1442     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1443         return this->GetAINavigationBarArea(displayId);
1444     };
1445     specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1446         this->OnOutsideDownEvent(x, y);
1447     };
1448     specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1449         return this->HandleSecureSessionShouldHide(sceneSession);
1450     };
1451     specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1452         this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1453     };
1454     specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1455         this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1456     };
1457     specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1458         this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1459     };
1460     specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1461         this->UpdateGestureBackEnabled(persistentId);
1462     };
1463     return specificCb;
1464 }
1465 
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1466 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1467 {
1468     TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1469     auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1470     if (isSkip) {
1471         if (it == skipSurfaceNodeIds_.end()) {
1472             skipSurfaceNodeIds_.push_back(surfaceNodeId);
1473         } else {
1474             return;
1475         }
1476     } else {
1477         if (it != skipSurfaceNodeIds_.end()) {
1478             skipSurfaceNodeIds_.erase(it);
1479         } else {
1480             return;
1481         }
1482     }
1483     rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1484 }
1485 
CreateKeyboardSessionCallback()1486 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1487 {
1488     sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1489         new (std::nothrow)KeyboardSession::KeyboardSessionCallback();
1490     if (keyboardCb == nullptr) {
1491         TLOGE(WmsLogTag::WMS_KEYBOARD, "KeyboardSessionCallback is nullptr");
1492         return keyboardCb;
1493     }
1494     keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1495         return this->GetSceneSession(persistentId);
1496     };
1497     keyboardCb->onGetFocusedSessionId_ = [this] {
1498         return this->GetFocusedSessionId();
1499     };
1500     keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1501 
1502     return keyboardCb;
1503 }
1504 
CheckWindowId(int32_t windowId,int32_t & pid)1505 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1506 {
1507     if (!SessionPermission::IsSystemCalling()) {
1508         TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1509         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1510     }
1511 
1512     auto task = [this, windowId, &pid]() -> WMError {
1513         pid = INVALID_PID;
1514         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1515         auto iter = sceneSessionMap_.find(windowId);
1516         if (iter == sceneSessionMap_.end()) {
1517             WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
1518             return WMError::WM_ERROR_INVALID_WINDOW;
1519         }
1520         auto sceneSession = iter->second;
1521         if (sceneSession == nullptr) {
1522             WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1523             return WMError::WM_ERROR_INVALID_WINDOW;
1524         }
1525         pid = sceneSession->GetCallingPid();
1526         WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1527         return WMError::WM_OK;
1528     };
1529     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1530 }
1531 
GetLockScreenZOrder()1532 uint32_t SceneSessionManager::GetLockScreenZOrder()
1533 {
1534     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1535     for (const auto& [persistentId, session] : sceneSessionMap_) {
1536         if (session && session->IsScreenLockWindow()) {
1537             TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: found window %{public}d", persistentId);
1538             return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
1539                 session->GetZOrder();
1540         }
1541     }
1542     TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
1543     return DEFAULT_LOCK_SCREEN_ZORDER;
1544 }
1545 
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)1546 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
1547     const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
1548 {
1549     std::ostringstream ss;
1550     ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
1551     return taskScheduler_->PostSyncTask([this, windowId, callingTokenId, &element, extensionAbilityType, &pid]() {
1552         pid = INVALID_PID;
1553         auto sceneSession = GetSceneSession(windowId);
1554         if (sceneSession == nullptr) {
1555             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
1556             return WMError::WM_ERROR_INVALID_WINDOW;
1557         }
1558         pid = sceneSession->GetCallingPid();
1559         if (!IsScreenLocked()) {
1560             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
1561             return WMError::WM_OK;
1562         }
1563         if (IsUserAuthPassed()) {
1564             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
1565             return WMError::WM_OK;
1566         }
1567         // 1. check window whether can show on main window
1568         if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
1569             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
1570             return WMError::WM_OK;
1571         }
1572         // 2. check permission
1573         if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
1574             TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
1575                 callingTokenId);
1576             return WMError::WM_ERROR_INVALID_PERMISSION;
1577         }
1578         TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: IsShowOnLockScreen: The caller permission has granted");
1579         return WMError::WM_OK;
1580     }, ss.str());
1581 }
1582 
1583 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)1584 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
1585 {
1586     taskScheduler_->PostSyncTask([this, &windowIds]() {
1587         // check every window
1588         for (auto windowId : windowIds) {
1589             auto sceneSession = GetSceneSession(windowId);
1590             if (!sceneSession) {
1591                 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
1592                 continue;
1593             }
1594             TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
1595             sceneSession->OnNotifyAboveLockScreen();
1596         }
1597         return WMError::WM_OK;
1598     }, __func__);
1599 }
1600 
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1601 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1602 {
1603     if (!isKeyboardPanelEnabled_) {
1604         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1605         return;
1606     }
1607     if (keyboardSession == nullptr) {
1608         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1609         return;
1610     }
1611     auto sessionProperty = keyboardSession->GetSessionProperty();
1612     if (sessionProperty == nullptr) {
1613         TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1614         return;
1615     }
1616     DisplayId displayId = sessionProperty->GetDisplayId();
1617     const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1618     sptr<SceneSession> panelSession;
1619     if (panelVec.size() > 1) {
1620         TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1621         return;
1622     } else if (panelVec.size() == 1) {
1623         panelSession = panelVec.front();
1624         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1625     } else {
1626         SessionInfo panelInfo = {
1627             .bundleName_ = "SCBKeyboardPanel",
1628             .moduleName_ = "SCBKeyboardPanel",
1629             .abilityName_ = "SCBKeyboardPanel",
1630             .isSystem_ = true,
1631             .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1632             .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1633             .screenId_ = static_cast<uint64_t>(displayId),
1634             .isRotable_ = true,
1635         };
1636         static bool is2in1 = systemConfig_.uiType_ == UI_TYPE_PC;
1637         if (is2in1) {
1638             panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1639             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1640         } else {
1641             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1642         }
1643         panelSession = RequestSceneSession(panelInfo, nullptr);
1644         if (panelSession == nullptr) {
1645             TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1646             return;
1647         }
1648     }
1649     keyboardSession->BindKeyboardPanelSession(panelSession);
1650     panelSession->BindKeyboardSession(keyboardSession);
1651     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1652         panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1653 }
1654 
OnSCBSystemSessionBufferAvailable(WindowType type)1655 void SceneSessionManager::OnSCBSystemSessionBufferAvailable(WindowType type)
1656 {
1657     TLOGI(WmsLogTag::WMS_MULTI_USER, "In");
1658     if (type == WindowType::WINDOW_TYPE_KEYGUARD) {
1659         TLOGI(WmsLogTag::WMS_MULTI_USER, "On screen lock buffer available");
1660     }
1661 }
1662 
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1663 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1664     sptr<WindowSessionProperty> property)
1665 {
1666     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1667     sptr<SceneSession> sceneSession = nullptr;
1668     if (sessionInfo.isSystem_) {
1669         sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
1670         WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1671         if (sceneSession != nullptr &&
1672             static_cast<OHOS::Rosen::WindowType>(sessionInfo.windowType_) == WindowType::WINDOW_TYPE_KEYGUARD) {
1673             TLOGI(WmsLogTag::WMS_MULTI_USER, "Register screen lock buffer available");
1674             sceneSession->RegisterBufferAvailableCallback([this] {
1675                 this->OnSCBSystemSessionBufferAvailable(WindowType::WINDOW_TYPE_KEYGUARD);
1676             });
1677         }
1678     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1679         sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
1680         if (sceneSession != nullptr) {
1681             TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1682         }
1683     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1684         sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
1685         TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1686     } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1687         sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1688         sceneSession = new (std::nothrow) KeyboardSession(sessionInfo, specificCb, keyboardCb);
1689         CreateKeyboardPanelSession(sceneSession);
1690         TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1691     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1692         sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
1693         TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1694     } else {
1695         TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1696     }
1697     if (sceneSession != nullptr) {
1698         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1699         sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1700         sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1701             return this->GetAppForceLandscapeConfig(bundleName);
1702         });
1703         sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1704             this->UpdatePrivateStateAndNotify(persistentId);
1705         });
1706         sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1707             this->NotifyVisibleChange(persistentId);
1708         });
1709         sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
1710             return this->IsLastFrameLayoutFinished(isLayoutFinished);
1711         });
1712         DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1713         GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
1714         sceneSession->SetAppDragResizeType(dragResizeType);
1715     }
1716     return sceneSession;
1717 }
1718 
GetEffectiveDragResizeType(DragResizeType & dragResizeType)1719 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
1720 {
1721     if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1722         return;
1723     }
1724     if (systemConfig_.freeMultiWindowSupport_) {
1725         dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
1726     } else {
1727         dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
1728     }
1729 }
1730 
SetGlobalDragResizeType(DragResizeType dragResizeType)1731 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
1732 {
1733     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1734     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1735         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1736         return WMError::WM_ERROR_INVALID_PERMISSION;
1737     }
1738     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1739     globalDragResizeType_ = dragResizeType;
1740     taskScheduler_->PostAsyncTask([this] {
1741         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1742         for (const auto& [_, sceneSession] : sceneSessionMap_) {
1743             if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1744                 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
1745                 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1746                 GetAppDragResizeType(bundleName, appDragResizeType);
1747                 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1748                     "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
1749                 sceneSession->SetAppDragResizeType(appDragResizeType);
1750             }
1751         }
1752     }, __func__);
1753     return WMError::WM_OK;
1754 }
1755 
GetGlobalDragResizeType(DragResizeType & dragResizeType)1756 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
1757 {
1758     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1759     dragResizeType = globalDragResizeType_;
1760     GetEffectiveDragResizeType(dragResizeType);
1761     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1762     return WMError::WM_OK;
1763 }
1764 
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)1765 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
1766 {
1767     TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1768         dragResizeType, bundleName.c_str());
1769     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1770         TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1771         return WMError::WM_ERROR_INVALID_PERMISSION;
1772     }
1773     return SetAppDragResizeTypeInner(bundleName, dragResizeType);
1774 }
1775 
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)1776 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
1777 {
1778     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1779         dragResizeType, bundleName.c_str());
1780     if (bundleName.empty()) {
1781         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1782         return WMError::WM_ERROR_INVALID_PARAM;
1783     }
1784     std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
1785     appDragResizeTypeMap_[bundleName] = dragResizeType;
1786     GetAppDragResizeTypeInner(bundleName, dragResizeType);
1787     taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
1788         auto sceneSession = GetSceneSessionByBundleName(bundleName);
1789         if (sceneSession != nullptr) {
1790             TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1791                 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
1792             sceneSession->SetAppDragResizeType(dragResizeType);
1793         }
1794     }, __func__);
1795     return WMError::WM_OK;
1796 }
1797 
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)1798 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
1799 {
1800     std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1801     return GetAppDragResizeTypeInner(bundleName, dragResizeType);
1802 }
1803 
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)1804 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
1805 {
1806     if (bundleName.empty()) {
1807         TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1808         return WMError::WM_ERROR_INVALID_PARAM;
1809     }
1810     if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1811         TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
1812         dragResizeType = globalDragResizeType_;
1813         return WMError::WM_OK;
1814     }
1815     dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1816     if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
1817         dragResizeType = iter->second;
1818     }
1819     GetEffectiveDragResizeType(dragResizeType);
1820     TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1821         dragResizeType, bundleName.c_str());
1822     return WMError::WM_OK;
1823 }
1824 
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)1825 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
1826 {
1827     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1828         auto session = GetSceneSession(sessionInfo.persistentId_);
1829         if (session != nullptr) {
1830             TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1831             return session;
1832         }
1833 
1834         if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1835             TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1836                 "abilityName: %{public}s, appIndex: %{public}d",
1837                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1838                 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1839             ComparedSessionInfo compareSessionInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_,
1840                 sessionInfo.appIndex_, sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1841             auto sceneSession = GetSceneSessionByName(compareSessionInfo);
1842             bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1843                 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1844             if (isSingleStart) {
1845                 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1846                     sessionInfo.persistentId_);
1847                 return sceneSession;
1848             }
1849         }
1850     }
1851     return nullptr;
1852 }
1853 
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1854 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1855     sptr<WindowSessionProperty> property)
1856 {
1857     const char* const where = __func__;
1858     auto task = [this, sessionInfo, property, where] {
1859         if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
1860             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1861             return session;
1862         }
1863         TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
1864             "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1865             where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1866             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1867             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1868         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1869         if (sceneSession == nullptr) {
1870             TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1871             return sceneSession;
1872         }
1873         InitSceneSession(sceneSession, sessionInfo, property);
1874         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1875             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1876                 where, sceneSession->GetSessionInfo().ancoSceneState);
1877             bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1878             const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1879             if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1880                 TLOGNI(WmsLogTag::WMS_LIFE,
1881                     "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1882                     where, reusedSceneSession->GetPersistentId(),
1883                     reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1884                 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1885                 return reusedSceneSession;
1886             }
1887             if (isPreHandleSuccess) {
1888                 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1889                 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1890             }
1891         }
1892         {
1893             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1894             sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1895         }
1896         PerformRegisterInRequestSceneSession(sceneSession);
1897         TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession id: %{public}d, type: %{public}d",
1898             sceneSession->GetPersistentId(), sceneSession->GetWindowType());
1899         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1900         return sceneSession;
1901     };
1902     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1903 }
1904 
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)1905 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1906     const sptr<WindowSessionProperty>& property)
1907 {
1908     auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1909     DisplayId curDisplayId = DISPLAY_ID_INVALID;
1910     if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1911         curDisplayId = sessionInfo.screenId_;
1912     } else if (callerSession) {
1913         auto callerSessionProperty = callerSession->GetSessionProperty();
1914         if (callerSessionProperty) {
1915             curDisplayId = callerSessionProperty->GetDisplayId();
1916         }
1917     }
1918     auto sessionProperty = sceneSession->GetSessionProperty();
1919     if (sessionProperty) {
1920         sessionProperty->SetDisplayId(curDisplayId);
1921         sceneSession->SetScreenId(curDisplayId);
1922         TLOGD(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
1923             curDisplayId);
1924     }
1925     sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
1926     sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
1927     if (sessionInfo.isSystem_) {
1928         sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1929         sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1930         auto rootContext = rootSceneContextWeak_.lock();
1931         sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1932     } else {
1933         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
1934             "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
1935             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1936             sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1937     }
1938     RegisterSessionExceptionFunc(sceneSession);
1939     // Skip FillSessionInfo when atomicService free-install start.
1940     if (!IsAtomicServiceFreeInstall(sessionInfo)) {
1941         FillSessionInfo(sceneSession);
1942     }
1943     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
1944     if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
1945         sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
1946     }
1947     sceneSession->SetSystemConfig(systemConfig_);
1948     sceneSession->SetSnapshotScale(snapshotScale_);
1949     UpdateParentSessionForDialog(sceneSession, property);
1950 }
1951 
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)1952 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1953 {
1954     sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
1955     if (info == nullptr) {
1956         WLOGFE("new info failed");
1957         return;
1958     }
1959     info->action_ = action;
1960     info->abilityName_ = sessionInfo.abilityName_;
1961     info->bundleName_ = sessionInfo.bundleName_;
1962     info->toScreenId_ = sessionInfo.screenId_;
1963     info->fromScreenId_ = fromScreenId;
1964     ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1965     WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
1966         info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1967 }
1968 
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)1969 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1970 {
1971     RegisterSessionSnapshotFunc(sceneSession);
1972     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1973     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1974     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1975     RegisterGetStateFromManagerFunc(sceneSession);
1976     RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
1977     RegisterAcquireRotateAnimationConfigFunc(sceneSession);
1978 }
1979 
UpdateSceneSessionWant(const SessionInfo & sessionInfo)1980 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1981 {
1982     if (sessionInfo.persistentId_ != 0) {
1983         auto session = GetSceneSession(sessionInfo.persistentId_);
1984         if (session != nullptr && sessionInfo.want != nullptr) {
1985             TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
1986             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1987                 session->SetSessionInfoWant(sessionInfo.want);
1988                 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
1989             } else {
1990                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1991             }
1992         } else {
1993             TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
1994                 session == nullptr, sessionInfo.persistentId_);
1995         }
1996     } else {
1997         TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
1998     }
1999 }
2000 
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2001 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2002 {
2003     if (session != nullptr) {
2004         if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2005             FillSessionInfo(session);
2006             if (CheckCollaboratorType(session->GetCollaboratorType())) {
2007                 PreHandleCollaborator(session, persistentId);
2008             }
2009         }
2010     }
2011 }
2012 
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)2013 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
2014 {
2015     sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
2016     if (abilitySessionInfo == nullptr) {
2017         WLOGFE("abilitySessionInfo is nullptr");
2018         return nullptr;
2019     }
2020     auto sessionInfo = scnSession->GetSessionInfo();
2021     sptr<ISession> iSession(scnSession);
2022     abilitySessionInfo->sessionToken = iSession->AsObject();
2023     abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2024         std::chrono::system_clock::now()).time_since_epoch().count());
2025     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2026     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2027         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2028     abilitySessionInfo->persistentId = scnSession->GetPersistentId();
2029     abilitySessionInfo->requestCode = sessionInfo.requestCode;
2030     abilitySessionInfo->resultCode = sessionInfo.resultCode;
2031     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2032     abilitySessionInfo->startSetting = sessionInfo.startSetting;
2033     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2034     abilitySessionInfo->userId = currentUserId_;
2035     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2036     abilitySessionInfo->processOptions = sessionInfo.processOptions;
2037     if (sessionInfo.want != nullptr) {
2038         abilitySessionInfo->want = *sessionInfo.want;
2039     } else {
2040         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2041             sessionInfo.moduleName_);
2042     }
2043     int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2044     bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2045     if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2046         TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2047             appIndex, sessionInfo.appIndex_);
2048     }
2049     if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2050         TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2051         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2052     }
2053     auto sessionProperty = scnSession->GetSessionProperty();
2054     if (sessionProperty) {
2055         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2056             static_cast<int>(sessionProperty->GetDisplayId()));
2057     }
2058     if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2059         sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2060         abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2061     } else {
2062         TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2063     }
2064     return abilitySessionInfo;
2065 }
2066 
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2067 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2068 {
2069     if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2070         isPrepareTerminate = false;
2071         TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2072         return WSError::WS_OK;
2073     }
2074     auto sceneSession = GetSceneSession(persistentId);
2075     if (sceneSession == nullptr) {
2076         TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2077         isPrepareTerminate = false;
2078         return WSError::WS_ERROR_NULLPTR;
2079     }
2080     auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2081     if (sceneSessionInfo == nullptr) {
2082         TLOGE(WmsLogTag::WMS_MAIN, "sceneSessionInfo is null, Id:%{public}d", persistentId);
2083         isPrepareTerminate = false;
2084         return WSError::WS_ERROR_NULLPTR;
2085     }
2086     auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2087         PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2088     TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2089         "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2090     return WSError::WS_OK;
2091 }
2092 
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)2093 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
2094 {
2095     wptr<SceneSession> weakSceneSession(sceneSession);
2096     auto task = [this, weakSceneSession, isNewActive]() {
2097         sptr<SceneSession> scnSession = weakSceneSession.promote();
2098         if (scnSession == nullptr) {
2099             TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2100             return WSError::WS_ERROR_NULLPTR;
2101         }
2102         auto persistentId = scnSession->GetPersistentId();
2103         if (!Session::IsScbCoreEnabled()) {
2104             scnSession->SetForegroundInteractiveStatus(true);
2105         }
2106         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2107         TLOGI(WmsLogTag::WMS_MAIN, "Request active id:%{public}d system:%{public}u isNewActive:%{public}d",
2108             persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_), isNewActive);
2109         if (!GetSceneSession(persistentId)) {
2110             TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2111             return WSError::WS_ERROR_INVALID_SESSION;
2112         }
2113         auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
2114         if (ret == WSError::WS_OK) {
2115             scnSession->SetExitSplitOnBackground(false);
2116         }
2117         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
2118         return ret;
2119     };
2120     std::string taskName = "RequestSceneSessionActivation:PID:" +
2121         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2122     taskScheduler_->PostAsyncTask(task, taskName);
2123     return WSError::WS_OK;
2124 }
2125 
IsKeyboardForeground()2126 bool SceneSessionManager::IsKeyboardForeground()
2127 {
2128     bool isKeyboardForeground = false;
2129     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2130     for (const auto &item : sceneSessionMap_) {
2131         auto sceneSession = item.second;
2132         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2133             isKeyboardForeground = sceneSession->IsSessionForeground();
2134             break;
2135         }
2136     }
2137 
2138     return isKeyboardForeground;
2139 }
2140 
RequestInputMethodCloseKeyboard(const int32_t persistentId)2141 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
2142 {
2143     auto sceneSession = GetSceneSession(persistentId);
2144     if (sceneSession == nullptr) {
2145         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
2146         return;
2147     }
2148     // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
2149     if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
2150         !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
2151         TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
2152             persistentId, sceneSession->GetSessionState());
2153         sceneSession->RequestHideKeyboard(true);
2154     }
2155 }
2156 
StartUIAbilityBySCB(sptr<SceneSession> & scnSession)2157 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
2158 {
2159     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2160     if (abilitySessionInfo == nullptr) {
2161         return ERR_NULL_OBJECT;
2162     }
2163     return StartUIAbilityBySCB(abilitySessionInfo);
2164 }
2165 
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)2166 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
2167 {
2168     bool isColdStart = false;
2169     return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
2170 }
2171 
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession> & scnSession,bool visibility)2172 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
2173 {
2174     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2175     if (abilitySessionInfo == nullptr) {
2176         return ERR_NULL_OBJECT;
2177     }
2178     return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
2179 }
2180 
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive)2181 WSError SceneSessionManager::RequestSceneSessionActivationInner(
2182     sptr<SceneSession>& scnSession, bool isNewActive)
2183 {
2184     auto persistentId = scnSession->GetPersistentId();
2185     RequestInputMethodCloseKeyboard(persistentId);
2186     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2187         scnSession->SetIsStarting(true);
2188         scnSession->SetStartingBeforeVisible(true);
2189     }
2190     if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
2191         if (Session::IsScbCoreEnabled()) {
2192             if (scnSession->IsVisibleForeground()) {
2193                 RequestSessionFocusImmediately(persistentId);
2194             } else {
2195                 PostProcessFocusState state = { true, true, FocusChangeReason::SCB_START_APP };
2196                 scnSession->SetPostProcessFocusState(state);
2197             }
2198         } else {
2199             RequestSessionFocusImmediately(persistentId);
2200         }
2201     }
2202     if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2203         FillSessionInfo(scnSession);
2204         if (!PreHandleCollaborator(scnSession, persistentId)) {
2205             TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
2206                 persistentId, scnSession->GetSessionInfo().ancoSceneState);
2207             scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
2208             return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
2209         }
2210     }
2211     auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2212     if (!scnSessionInfo) {
2213         TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
2214         return WSError::WS_ERROR_NULLPTR;
2215     }
2216     scnSession->NotifyActivation();
2217     scnSessionInfo->isNewWant = isNewActive;
2218     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2219         scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
2220         scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
2221     }
2222     TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
2223         "module: %{public}s, uri: %{public}s, appIndex: %{public}d.", persistentId,
2224         scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
2225         scnSessionInfo->want.GetElement().GetBundleName().c_str(),
2226         scnSessionInfo->want.GetElement().GetModuleName().c_str(),
2227         scnSessionInfo->want.GetElement().GetURI().c_str(),
2228         scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0));
2229     int32_t errCode = ERR_OK;
2230     bool isColdStart = false;
2231     bool isAppSupportPhoneInPc = false;
2232     auto sessionProperty = scnSession->GetSessionProperty();
2233     if (sessionProperty != nullptr) {
2234         isAppSupportPhoneInPc = sessionProperty->GetIsAppSupportPhoneInPc();
2235     }
2236     if (systemConfig_.backgroundswitch == false || isAppSupportPhoneInPc) {
2237         TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
2238             static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2239         errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2240     } else {
2241         TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
2242             isNewActive, scnSession->GetSessionState());
2243         if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
2244             scnSession->GetSessionState() == SessionState::STATE_END) {
2245             TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
2246                 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2247             errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2248         } else {
2249             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
2250             scnSession->NotifySessionForeground(1, true);
2251         }
2252     }
2253     auto sessionInfo = scnSession->GetSessionInfo();
2254     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2255         WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
2256     }
2257     NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
2258 
2259     if (errCode != ERR_OK) {
2260         TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
2261         scnSession->NotifySessionExceptionInner(scnSessionInfo, true, false, true);
2262         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
2263             startUIAbilityErrorFunc_(
2264                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
2265         }
2266     }
2267     if (isColdStart) {
2268         TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
2269             scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
2270         scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
2271         scnSession->ResetSessionConnectState();
2272         scnSession->ResetIsActive();
2273     }
2274     return WSError::WS_OK;
2275 }
2276 
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)2277 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
2278     sptr<AAFwk::SessionInfo>& scnSessionInfo)
2279 {
2280     if (scnSession == nullptr || scnSessionInfo == nullptr) {
2281         return;
2282     }
2283     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2284         NotifyLoadAbility(scnSession->GetCollaboratorType(),
2285             scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
2286         NotifyUpdateSessionInfo(scnSession);
2287         NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2288         scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2289     }
2290 }
2291 
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)2292 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2293     const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2294 {
2295     wptr<SceneSession> weakSceneSession(sceneSession);
2296     auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
2297         auto scnSession = weakSceneSession.promote();
2298         if (scnSession == nullptr) {
2299             TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
2300             return WSError::WS_ERROR_NULLPTR;
2301         }
2302         auto persistentId = scnSession->GetPersistentId();
2303         TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2304             "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2305             persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2306         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2307         scnSession->SetActive(false);
2308 
2309         if (isToDesktop) {
2310             auto info = scnSession->GetSessionInfo();
2311             info.callerToken_ = nullptr;
2312             info.callingTokenId_ = 0;
2313             scnSession->SetSessionInfo(info);
2314         }
2315 
2316         scnSession->BackgroundTask(isSaveSnapshot);
2317         if (!GetSceneSession(persistentId)) {
2318             TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2319             return WSError::WS_ERROR_INVALID_SESSION;
2320         }
2321         if (persistentId == brightnessSessionId_) {
2322             UpdateBrightness(focusedSessionId_);
2323         }
2324         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2325         if (!scnSessionInfo) {
2326             TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2327             return WSError::WS_ERROR_NULLPTR;
2328         }
2329         bool isPcAppInpad = false;
2330         bool isAppSupportPhoneInPc = false;
2331         auto property = scnSession->GetSessionProperty();
2332         if (property) {
2333             isPcAppInpad = property->GetIsPcAppInPad();
2334             isAppSupportPhoneInPc = property->GetIsAppSupportPhoneInPc();
2335         }
2336         if ((systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || isPcAppInpad) {
2337             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2338             scnSession->NotifySessionBackground(1, true, true);
2339         } else {
2340             TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2341                 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2342             if (!isDelegator) {
2343                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2344             } else {
2345                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2346             }
2347         }
2348 
2349         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2350             auto sessionInfo = scnSession->GetSessionInfo();
2351             WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2352         }
2353         return WSError::WS_OK;
2354     };
2355     std::string taskName = "RequestSceneSessionBackground:PID:" +
2356         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2357     taskScheduler_->PostAsyncTask(task, taskName);
2358     return WSError::WS_OK;
2359 }
2360 
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2361 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2362 {
2363     wptr<SceneSession> weakSceneSession(sceneSession);
2364     auto task = [this, weakSceneSession, interactive]() {
2365         auto scnSession = weakSceneSession.promote();
2366         if (scnSession == nullptr) {
2367             WLOGFE("session is nullptr");
2368             return;
2369         }
2370         auto persistentId = scnSession->GetPersistentId();
2371         WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2372         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2373         if (!GetSceneSession(persistentId)) {
2374             WLOGFE("session is invalid with %{public}d", persistentId);
2375             return;
2376         }
2377         scnSession->NotifyForegroundInteractiveStatus(interactive);
2378     };
2379 
2380     taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2381 }
2382 
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)2383 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2384 {
2385     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2386     if (scnSession == nullptr) {
2387         TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2388         return WSError::WS_ERROR_NULLPTR;
2389     }
2390     if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2391         TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2392         auto dialogVec = scnSession->GetDialogVector();
2393         for (auto dialog : dialogVec) {
2394             if (dialog == nullptr) {
2395                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2396                 continue;
2397             }
2398             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2399             if (sceneSession == nullptr) {
2400                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2401                 return WSError::WS_ERROR_INVALID_SESSION;
2402             }
2403             WindowDestroyNotifyVisibility(sceneSession);
2404             dialog->NotifyDestroy();
2405             dialog->Disconnect();
2406 
2407             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2408             if (dialogSceneSession != nullptr) {
2409                 dialogSceneSession->ClearSpecificSessionCbMap();
2410             }
2411             {
2412                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2413                 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2414                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2415                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2416             }
2417         }
2418         scnSession->ClearDialogVector();
2419         return WSError::WS_OK;
2420     }
2421     return WSError::WS_ERROR_INVALID_SESSION;
2422 }
2423 
DestroySubSession(const sptr<SceneSession> & sceneSession)2424 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2425 {
2426     if (sceneSession == nullptr) {
2427         WLOGFW("sceneSession is nullptr");
2428         return;
2429     }
2430     for (const auto& elem : sceneSession->GetSubSession()) {
2431         if (elem != nullptr) {
2432             const auto& persistentId = elem->GetPersistentId();
2433             TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2434             DestroyAndDisconnectSpecificSessionInner(persistentId);
2435         }
2436     }
2437 }
2438 
DestroyToastSession(const sptr<SceneSession> & sceneSession)2439 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2440 {
2441     if (sceneSession == nullptr) {
2442         TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2443         return;
2444     }
2445     for (const auto& elem : sceneSession->GetToastSession()) {
2446         if (elem != nullptr) {
2447             const auto& persistentId = elem->GetPersistentId();
2448             TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2449             DestroyAndDisconnectSpecificSessionInner(persistentId);
2450         }
2451     }
2452 }
2453 
EraseSceneSessionMapById(int32_t persistentId)2454 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2455 {
2456     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2457     EraseSceneSessionAndMarkDirtyLocked(persistentId);
2458     systemTopSceneSessionMap_.erase(persistentId);
2459     nonSystemFloatSceneSessionMap_.erase(persistentId);
2460 }
2461 
2462 /**
2463  * if visible session is erased, mark dirty
2464  * lock-free
2465  */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2466 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2467 {
2468     // get scene session lock-free
2469     auto iter = sceneSessionMap_.find(persistentId);
2470     if (iter == sceneSessionMap_.end()) {
2471         TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2472         return;
2473     }
2474     sptr<SceneSession> sceneSession = iter->second;
2475     if (sceneSession != nullptr && sceneSession->IsVisible()) {
2476         sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2477     }
2478     sceneSessionMap_.erase(persistentId);
2479 }
2480 
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean)2481 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2482     bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2483 {
2484     auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2485         needRemoveSession, isSaveSnapshot, isForceClean]() {
2486         auto scnSession = weakSceneSession.promote();
2487         if (scnSession == nullptr) {
2488             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2489             return WSError::WS_ERROR_NULLPTR;
2490         }
2491         auto persistentId = scnSession->GetPersistentId();
2492         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2493         RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2494         lastUpdatedAvoidArea_.erase(persistentId);
2495         DestroyDialogWithMainWindow(scnSession);
2496         DestroyToastSession(scnSession);
2497         DestroySubSession(scnSession); // destroy sub session by destruction
2498         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2499             " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2500         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2501         WindowDestroyNotifyVisibility(scnSession);
2502         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2503         scnSession->DisconnectTask(false, isSaveSnapshot);
2504         if (!GetSceneSession(persistentId)) {
2505             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2506             return WSError::WS_ERROR_INVALID_SESSION;
2507         }
2508         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2509         if (!scnSessionInfo) {
2510             return WSError::WS_ERROR_NULLPTR;
2511         }
2512         scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2513         ResetSceneSessionInfoWant(scnSessionInfo);
2514         return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2515     };
2516     std::string taskName = "RequestSceneSessionDestruction:PID:" +
2517         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2518     taskScheduler_->PostAsyncTask(task, taskName);
2519     return WSError::WS_OK;
2520 }
2521 
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)2522 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
2523 {
2524     if (sceneSessionInfo->resultCode == -1) {
2525         AAFwk::Want want;
2526         std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2527         want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2528         sceneSessionInfo->want = std::move(want);
2529         TLOGI(WmsLogTag::WMS_MAIN, "sceneSessionInfo.resultCode: %{public}d, keySessionId: %{public}s",
2530             sceneSessionInfo->resultCode, keySessionId.c_str());
2531     }
2532 }
2533 
ResetWant(sptr<SceneSession> & sceneSession)2534 void SceneSessionManager::ResetWant(sptr<SceneSession>& sceneSession)
2535 {
2536     auto& sessionInfo = sceneSession->GetSessionInfo();
2537     if (sessionInfo.want != nullptr) {
2538         const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2539         const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2540         const auto& keySessionId = sessionInfo.want->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2541         auto want = std::make_shared<AAFwk::Want>();
2542         if (want != nullptr) {
2543             AppExecFwk::ElementName element;
2544             element.SetBundleName(bundleName);
2545             element.SetAbilityName(abilityName);
2546             want->SetElement(element);
2547             want->SetBundle(bundleName);
2548             if (!keySessionId.empty()) {
2549                 want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2550             }
2551             sceneSession->SetSessionInfoWant(want);
2552         }
2553     }
2554 }
2555 
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession,const bool isForceClean)2556 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& scnSession,
2557     sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2558 {
2559     auto persistentId = scnSession->GetPersistentId();
2560     TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}u",
2561         persistentId,
2562         static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2563     if (isForceClean) {
2564         AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2565     } else {
2566         AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2567     }
2568     scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2569     if (needRemoveSession) {
2570         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2571             NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2572         }
2573         EraseSceneSessionMapById(persistentId);
2574     } else {
2575         // if terminate, reset want. so start from recent, start a new one.
2576         TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2577         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2578             scnSession->SetSessionInfoWant(nullptr);
2579         }
2580         ResetWant(scnSession);
2581         scnSession->ResetSessionInfoResultCode();
2582     }
2583     if (listenerController_ != nullptr) {
2584         NotifySessionForCallback(scnSession, needRemoveSession);
2585     }
2586     scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2587     return WSError::WS_OK;
2588 }
2589 
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)2590 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2591     const sptr<SceneSession>& sceneSession)
2592 {
2593     if (sceneSession == nullptr || sessionStage == nullptr) {
2594         TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2595         return;
2596     }
2597 
2598     auto remoteObject = sessionStage->AsObject();
2599     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2600     if (windowDeath_ == nullptr) {
2601         TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2602         return;
2603     }
2604     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2605         TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2606         return;
2607     }
2608     WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2609 }
2610 
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)2611 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2612 {
2613     auto task = [this, remoteObject]() {
2614         auto iter = remoteObjectMap_.find(remoteObject);
2615         if (iter == remoteObjectMap_.end()) {
2616             WLOGFE("Invalid remoteObject");
2617             return;
2618         }
2619         WLOGFD("Remote died, id: %{public}d", iter->second);
2620         auto session = GetSceneSession(iter->second);
2621         if (session == nullptr) {
2622             WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2623             return;
2624         }
2625         DestroyAndDisconnectSpecificSessionInner(iter->second);
2626     };
2627     taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2628 }
2629 
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)2630 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2631     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2632     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2633     SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2634 {
2635     if (property == nullptr) {
2636         WLOGFE("property is nullptr");
2637         return WSError::WS_ERROR_NULLPTR;
2638     }
2639 
2640     if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2641         WLOGFE("create system window or modal subwindow permission denied!");
2642         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2643     }
2644 
2645     bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2646                         property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2647     bool isSystemCalling = SessionPermission::IsSystemCalling();
2648     if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2649         auto parentSession = GetSceneSession(property->GetParentPersistentId());
2650         if (parentSession) {
2651             shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2652         }
2653     }
2654     bool isPcWindow = false;
2655     IsPcWindow(isPcWindow);
2656     if (isPcWindow && property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
2657         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't block");
2658         shouldBlock = false;
2659     }
2660     if (shouldBlock) {
2661         TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2662         return WSError::WS_ERROR_INVALID_OPERATION;
2663     }
2664 
2665     if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2666         property->GetExtensionFlag() && property->GetIsUIExtensionAbilityProcess() &&
2667         SessionPermission::IsStartedByUIExtension()) {
2668         auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2669         if (extensionParentSession == nullptr) {
2670             WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2671             return WSError::WS_ERROR_NULLPTR;
2672         }
2673         SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2674         AAFwk::UIExtensionHostInfo hostInfo;
2675         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2676         if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2677             WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2678                 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2679                 hostInfo.elementName_.GetBundleName().c_str());
2680             return WSError::WS_ERROR_INVALID_WINDOW;
2681         }
2682     }
2683 
2684     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2685     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2686         WLOGFE("The alarm window has been deprecated!");
2687         return WSError::WS_ERROR_INVALID_WINDOW;
2688     }
2689 
2690     if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2691         WLOGFE("pip window is not enable to create.");
2692         return WSError::WS_DO_NOTHING;
2693     }
2694     TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2695         property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2696 
2697     // Get pid and uid before posting task.
2698     auto pid = IPCSkeleton::GetCallingRealPid();
2699     auto uid = IPCSkeleton::GetCallingUid();
2700     auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2701                     &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2702         if (property == nullptr) {
2703             WLOGFE("[WMSSub][WMSSystem] property is nullptr");
2704             return WSError::WS_ERROR_NULLPTR;
2705         }
2706         const auto& type = property->GetWindowType();
2707         // create specific session
2708         SessionInfo info;
2709         info.windowType_ = static_cast<uint32_t>(type);
2710         info.bundleName_ = property->GetSessionInfo().bundleName_;
2711         info.abilityName_ = property->GetSessionInfo().abilityName_;
2712         info.moduleName_ = property->GetSessionInfo().moduleName_;
2713 
2714         ClosePipWindowIfExist(type);
2715         sptr<SceneSession> newSession = RequestSceneSession(info, property);
2716         if (newSession == nullptr) {
2717             TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2718             return WSError::WS_ERROR_NULLPTR;
2719         }
2720         property->SetSystemCalling(isSystemCalling);
2721         auto errCode = newSession->ConnectInner(
2722             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2723         newSession->SetIsSystemSpecificSession(isSystemCalling);
2724         systemConfig = systemConfig_;
2725         if (property) {
2726             persistentId = property->GetPersistentId();
2727         }
2728 
2729         NotifyCreateSpecificSession(newSession, property, type);
2730         session = newSession;
2731         AddClientDeathRecipient(sessionStage, newSession);
2732         TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2733             "parentId: %{public}d, type: %{public}d",
2734             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2735         return errCode;
2736     };
2737 
2738     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2739 }
2740 
ClosePipWindowIfExist(WindowType type)2741 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2742 {
2743     if (type != WindowType::WINDOW_TYPE_PIP) {
2744         return;
2745     }
2746     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2747     for (const auto& iter: sceneSessionMap_) {
2748         auto& session = iter.second;
2749         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2750             session->NotifyCloseExistPipWindow();
2751             break;
2752         }
2753     }
2754 }
2755 
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)2756 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2757 {
2758     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2759     for (const auto& iter: sceneSessionMap_) {
2760         auto& session = iter.second;
2761         if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2762             pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2763             session->IsSessionForeground()) {
2764             if (startPiPFailedFunc_) {
2765                 startPiPFailedFunc_();
2766             }
2767             TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2768             return false;
2769         }
2770     }
2771     return true;
2772 }
2773 
isEnablePiPCreate(const sptr<WindowSessionProperty> & property)2774 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2775 {
2776     if (isScreenLocked_) {
2777         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2778         return false;
2779     }
2780     Rect pipRect = property->GetRequestRect();
2781     if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2782         TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2783         return false;
2784     }
2785     if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2786         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2787         return false;
2788     }
2789     auto parentSession = GetSceneSession(property->GetParentPersistentId());
2790     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2791         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2792         return false;
2793     }
2794     return true;
2795 }
2796 
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)2797 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2798 {
2799     WindowType type = property->GetWindowType();
2800     if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
2801         return true;
2802     }
2803 
2804     if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
2805         TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
2806         return false;
2807     }
2808 
2809     if (!SessionPermission::IsSystemCalling()) {
2810         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
2811         return false;
2812     }
2813 
2814     return true;
2815 }
2816 
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)2817 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
2818 {
2819     WindowType type = property->GetWindowType();
2820     if (WindowHelper::IsUIExtensionWindow(type)) {
2821         // UIExtension window disallowed.
2822         return false;
2823     }
2824     if (!WindowHelper::IsSystemWindow(type)) {
2825         // type is not system
2826         return true;
2827     }
2828     if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)
2829         && SessionPermission::IsStartedByInputMethod()) {
2830         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
2831         WLOGFD("check create permission success, input method app create input method window.");
2832         return true;
2833     }
2834     if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
2835         // some system types could be created by normal app
2836         return true;
2837     }
2838     if (type == WindowType::WINDOW_TYPE_FLOAT &&
2839         SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2840         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
2841         if (systemConfig_.supportTypeFloatWindow_) {
2842             WLOGFD("check create float window permission success on 2in1 device.");
2843             return true;
2844         }
2845     }
2846     if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
2847         int32_t parentId = property->GetParentPersistentId();
2848         auto parentSession = GetSceneSession(parentId);
2849         if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2850             SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2851             TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
2852             return true;
2853         } else {
2854             TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
2855         }
2856     }
2857     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
2858         TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
2859         return true;
2860     }
2861     WLOGFE("check system window permission failed.");
2862     return false;
2863 }
2864 
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)2865 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
2866 {
2867     SessionInfo sessionInfo;
2868     if (property == nullptr) {
2869         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2870         return sessionInfo;
2871     }
2872     sessionInfo = property->GetSessionInfo();
2873     sessionInfo.persistentId_ = property->GetPersistentId();
2874     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
2875     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
2876     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
2877     sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
2878                                     ? SessionState::STATE_ACTIVE
2879                                     : SessionState::STATE_BACKGROUND;
2880     sessionInfo.isPersistentRecover_ = true;
2881     TLOGI(WmsLogTag::WMS_RECOVER,
2882         "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
2883         "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
2884         "windowState=%{public}u",
2885         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2886         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_);
2887     return sessionInfo;
2888 }
2889 
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)2890 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
2891 {
2892     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
2893            "%{public}d", alivePersistentIds.size(), currentUserId_.load());
2894     alivePersistentIds_ = alivePersistentIds;
2895 }
2896 
IsNeedRecover(const int32_t persistentId)2897 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
2898 {
2899     auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
2900     if (it == alivePersistentIds_.end()) {
2901         TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
2902         return false;
2903     }
2904     return true;
2905 }
2906 
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)2907 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
2908     bool isSpecificSession)
2909 {
2910     if (property == nullptr) {
2911         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2912         return WSError::WS_ERROR_NULLPTR;
2913     }
2914     if (!CheckSystemWindowPermission(property)) {
2915         TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
2916         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2917     }
2918     if (isSpecificSession) {
2919         if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
2920             return WSError::WS_ERROR_INVALID_PARAM;
2921         }
2922     } else {
2923         if (!IsNeedRecover(property->GetPersistentId())) {
2924             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2925             return WSError::WS_ERROR_INVALID_PARAM;
2926         }
2927     }
2928     return WSError::WS_OK;
2929 }
2930 
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)2931 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2932     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2933     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
2934 {
2935     auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
2936     if (propCheckRet != WSError::WS_OK) {
2937         return propCheckRet;
2938     }
2939     auto pid = IPCSkeleton::GetCallingRealPid();
2940     auto uid = IPCSkeleton::GetCallingUid();
2941     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
2942         if (recoveringFinished_) {
2943             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2944             return WSError::WS_ERROR_INVALID_OPERATION;
2945         }
2946         // recover specific session
2947         SessionInfo info = RecoverSessionInfo(property);
2948         TLOGI(WmsLogTag::WMS_RECOVER, "callingWindowId = %{public}" PRIu32, property->GetCallingSessionId());
2949         ClosePipWindowIfExist(property->GetWindowType());
2950         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
2951         if (sceneSession == nullptr) {
2952             TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
2953             return WSError::WS_ERROR_NULLPTR;
2954         }
2955 
2956         auto persistentId = sceneSession->GetPersistentId();
2957         if (persistentId != info.persistentId_) {
2958             TLOGE(WmsLogTag::WMS_RECOVER,
2959                 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
2960                 info.persistentId_, persistentId, property->GetParentPersistentId());
2961             failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
2962             EraseSceneSessionMapById(persistentId);
2963             return WSError::WS_ERROR_INVALID_SESSION;
2964         }
2965 
2966         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2967         if (errCode != WSError::WS_OK) {
2968             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
2969             EraseSceneSessionMapById(persistentId);
2970             return errCode;
2971         }
2972         NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
2973         CacheSubSessionForRecovering(sceneSession, property);
2974         NotifySessionUnfocusedToClient(persistentId);
2975         AddClientDeathRecipient(sessionStage, sceneSession);
2976         session = sceneSession;
2977         return errCode;
2978     };
2979     return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
2980 }
2981 
NotifyRecoveringFinished()2982 void SceneSessionManager::NotifyRecoveringFinished()
2983 {
2984     taskScheduler_->PostAsyncTask([this]() {
2985             TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
2986             recoveringFinished_ = true;
2987             recoverSubSessionCacheMap_.clear();
2988         }, "NotifyRecoveringFinished");
2989 }
2990 
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)2991 void SceneSessionManager::CacheSubSessionForRecovering(
2992     sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
2993 {
2994     if (recoveringFinished_) {
2995         TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
2996         return;
2997     }
2998 
2999     if (sceneSession == nullptr || property == nullptr) {
3000         TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
3001         return;
3002     }
3003 
3004     auto windowType = property->GetWindowType();
3005     if (!SessionHelper::IsSubWindow(windowType)) {
3006         return;
3007     }
3008 
3009     auto persistentId = property->GetParentPersistentId();
3010     if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
3011         return;
3012     }
3013 
3014     TLOGI(WmsLogTag::WMS_RECOVER,
3015         "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
3016         sceneSession->GetPersistentId(), persistentId);
3017 
3018     if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
3019         recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
3020     } else {
3021         recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
3022     }
3023 }
3024 
RecoverCachedSubSession(int32_t persistentId)3025 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
3026 {
3027     auto iter = recoverSubSessionCacheMap_.find(persistentId);
3028     if (iter == recoverSubSessionCacheMap_.end()) {
3029         return;
3030     }
3031 
3032     TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3033     for (auto& sceneSession : iter->second) {
3034         NotifyCreateSubSession(persistentId, sceneSession);
3035     }
3036     recoverSubSessionCacheMap_.erase(iter);
3037 }
3038 
NotifySessionUnfocusedToClient(int32_t persistentId)3039 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
3040 {
3041     if (listenerController_ != nullptr) {
3042         TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3043         listenerController_->NotifySessionUnfocused(persistentId);
3044     }
3045 }
3046 
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)3047 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
3048     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3049     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
3050 {
3051     auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
3052     if (propCheckRet != WSError::WS_OK) {
3053         return propCheckRet;
3054     }
3055     auto pid = IPCSkeleton::GetCallingRealPid();
3056     auto uid = IPCSkeleton::GetCallingUid();
3057     auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
3058         if (recoveringFinished_) {
3059             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3060             return WSError::WS_ERROR_INVALID_OPERATION;
3061         }
3062         if (recoverSceneSessionFunc_ == nullptr) {
3063             TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
3064             return WSError::WS_ERROR_NULLPTR;
3065         }
3066         SessionInfo sessionInfo = RecoverSessionInfo(property);
3067         sptr<SceneSession> sceneSession = nullptr;
3068         if (SessionHelper::IsMainWindow(property->GetWindowType())) {
3069             sceneSession = RequestSceneSession(sessionInfo, nullptr);
3070         } else {
3071             sceneSession = RequestSceneSession(sessionInfo, property);
3072         }
3073         if (sceneSession == nullptr) {
3074             TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
3075             return WSError::WS_ERROR_NULLPTR;
3076         }
3077         int32_t persistentId = sceneSession->GetPersistentId();
3078         if (persistentId != sessionInfo.persistentId_) {
3079             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
3080                 sessionInfo.persistentId_, persistentId);
3081             EraseSceneSessionMapById(persistentId);
3082             return WSError::WS_ERROR_INVALID_SESSION;
3083         }
3084         auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3085         if (ret != WSError::WS_OK) {
3086             TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
3087             EraseSceneSessionMapById(sessionInfo.persistentId_);
3088             return ret;
3089         }
3090         sceneSession->SetRecovered(true);
3091         recoverSceneSessionFunc_(sceneSession, sessionInfo);
3092         NotifySessionUnfocusedToClient(persistentId);
3093         session = sceneSession;
3094         return WSError::WS_OK;
3095     };
3096     return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
3097 }
3098 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)3099 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
3100 {
3101     TLOGI(WmsLogTag::WMS_RECOVER, "called");
3102     recoverSceneSessionFunc_ = func;
3103 }
3104 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)3105 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
3106 {
3107     createSystemSessionFunc_ = func;
3108 }
3109 
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)3110 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
3111 {
3112     createKeyboardSessionFunc_ = func;
3113 }
3114 
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)3115 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
3116 {
3117     startPiPFailedFunc_ = std::move(func);
3118 }
3119 
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)3120 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
3121     const NotifyCreateSubSessionFunc& func)
3122 {
3123     TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
3124     auto task = [this, persistentId, func]() {
3125         createSubSessionFuncMap_[persistentId] = func;
3126         RecoverCachedSubSession(persistentId);
3127         return WMError::WM_OK;
3128     };
3129     taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
3130 }
3131 
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)3132 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
3133     sptr<WindowSessionProperty> property, const WindowType& type)
3134 {
3135     if (newSession == nullptr) {
3136         WLOGFE("newSession is nullptr");
3137         return;
3138     }
3139     if (property == nullptr) {
3140         WLOGFE("property is nullptr");
3141         return;
3142     }
3143     if (SessionHelper::IsSystemWindow(type)) {
3144         if (type == WindowType::WINDOW_TYPE_FLOAT) {
3145             auto parentSession = GetSceneSession(property->GetParentPersistentId());
3146             if (parentSession != nullptr) {
3147                 newSession->SetParentSession(parentSession);
3148             }
3149         }
3150         if (type == WindowType::WINDOW_TYPE_TOAST) {
3151             NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
3152         }
3153         if (type != WindowType::WINDOW_TYPE_DIALOG) {
3154             if (WindowHelper::IsSystemSubWindow(type)) {
3155                 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3156             } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
3157                 && createKeyboardSessionFunc_) {
3158                 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
3159             } else if (createSystemSessionFunc_) {
3160                 createSystemSessionFunc_(newSession);
3161             }
3162             TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
3163                 newSession->GetPersistentId(), type);
3164         } else {
3165             TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, \
3166                 type:%{public}d", newSession->GetPersistentId(), type);
3167             return;
3168         }
3169     } else if (SessionHelper::IsSubWindow(type)) {
3170         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3171         TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
3172             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
3173     } else {
3174         TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
3175             newSession->GetPersistentId(), type);
3176     }
3177 }
3178 
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)3179 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
3180 {
3181     if (session == nullptr) {
3182         TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
3183         return;
3184     }
3185     auto iter = createSubSessionFuncMap_.find(persistentId);
3186     if (iter == createSubSessionFuncMap_.end()) {
3187         TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
3188         return;
3189     }
3190 
3191     sptr<SceneSession> parentSession = nullptr;
3192     if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
3193         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3194         parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
3195     } else {
3196         parentSession = GetSceneSession(persistentId);
3197     }
3198     if (parentSession == nullptr) {
3199         TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
3200             persistentId, session->GetPersistentId());
3201         return;
3202     }
3203     parentSession->AddSubSession(session);
3204     session->SetParentSession(parentSession);
3205     if (iter->second) {
3206         iter->second(session);
3207     }
3208     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
3209         persistentId, session->GetPersistentId());
3210 }
3211 
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)3212 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
3213     const std::map<int32_t, sptr<SceneSession>>& sessionMap)
3214 {
3215     if (persistentId == INVALID_SESSION_ID) {
3216         TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
3217         return nullptr;
3218     }
3219     auto iter = sessionMap.find(persistentId);
3220     if (iter == sessionMap.end()) {
3221         WLOGFD("Error found scene session with id: %{public}d", persistentId);
3222         return nullptr;
3223     }
3224     sptr<SceneSession> parentSession = iter->second;
3225     if (parentSession == nullptr) {
3226         TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
3227         return nullptr;
3228     }
3229     bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
3230         parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
3231     if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
3232         TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
3233         return parentSession;
3234     }
3235     return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
3236 }
3237 
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)3238 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
3239 {
3240     if (session == nullptr) {
3241         TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
3242         return;
3243     }
3244 
3245     auto parentSession = GetSceneSession(persistentId);
3246     if (parentSession == nullptr) {
3247         TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
3248             persistentId, session->GetPersistentId());
3249         return;
3250     }
3251     parentSession->AddToastSession(session);
3252     session->SetParentSession(parentSession);
3253     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
3254         persistentId, session->GetPersistentId());
3255 }
3256 
UnregisterCreateSubSessionListener(int32_t persistentId)3257 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
3258 {
3259     TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
3260     auto task = [this, persistentId]() {
3261         auto iter = createSubSessionFuncMap_.find(persistentId);
3262         if (iter != createSubSessionFuncMap_.end()) {
3263             createSubSessionFuncMap_.erase(persistentId);
3264         } else {
3265             TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
3266         }
3267         return WMError::WM_OK;
3268     };
3269     taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
3270 }
3271 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)3272 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
3273 {
3274     WLOGFD("SetStatusBarEnabledChangeListener");
3275     if (!func) {
3276         WLOGFD("set func is null");
3277     }
3278     statusBarEnabledChangeFunc_ = func;
3279 }
3280 
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)3281 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
3282     const ProcessGestureNavigationEnabledChangeFunc& func)
3283 {
3284     WLOGFD("SetGestureNavigationEnabledChangeListener");
3285     if (!func) {
3286         WLOGFD("set func is null");
3287     }
3288     gestureNavigationEnabledChangeFunc_ = func;
3289 }
3290 
OnOutsideDownEvent(int32_t x,int32_t y)3291 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
3292 {
3293     TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
3294     if (outsideDownEventFunc_) {
3295         outsideDownEventFunc_(x, y);
3296     }
3297 }
3298 
NotifySessionTouchOutside(int32_t persistentId)3299 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
3300 {
3301     auto task = [this, persistentId]() {
3302         int32_t callingSessionId = INVALID_SESSION_ID;
3303         auto sceneSession = GetSceneSession(persistentId);
3304         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3305             callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
3306             TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
3307                 persistentId, callingSessionId);
3308         }
3309         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3310         for (const auto &item : sceneSessionMap_) {
3311             sceneSession = item.second;
3312             if (sceneSession == nullptr) {
3313                 continue;
3314             }
3315             if (!(sceneSession->IsVisible() ||
3316                 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3317                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
3318                 continue;
3319             }
3320             auto sessionId = sceneSession->GetPersistentId();
3321             if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
3322                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3323                 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3324                 continue;
3325             }
3326             if (sessionId == callingSessionId || sessionId == persistentId) {
3327                 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3328                 continue;
3329             }
3330             sceneSession->NotifyTouchOutside();
3331         }
3332     };
3333 
3334     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3335     return;
3336 }
3337 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)3338 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3339 {
3340     WLOGFD("SetOutsideDownEventListener");
3341     outsideDownEventFunc_ = func;
3342 }
3343 
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)3344 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
3345 {
3346     for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
3347         if (iter->second != persistentId) {
3348             continue;
3349         }
3350         if (windowDeath_ == nullptr) {
3351             TLOGE(WmsLogTag::WMS_LIFE, "death recipient is null");
3352         } else {
3353             if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
3354                 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
3355             }
3356         }
3357         remoteObjectMap_.erase(iter);
3358         break;
3359     }
3360 }
3361 
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3362 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3363 {
3364     auto sceneSession = GetSceneSession(persistentId);
3365     if (sceneSession == nullptr) {
3366         return WSError::WS_ERROR_NULLPTR;
3367     }
3368     auto ret = sceneSession->UpdateActiveStatus(false);
3369     WindowDestroyNotifyVisibility(sceneSession);
3370     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
3371         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3372         if (parentSession == nullptr) {
3373             TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3374         } else {
3375             parentSession->RemoveDialogToParentSession(sceneSession);
3376         }
3377     }
3378     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_TOAST) {
3379         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3380         if (parentSession != nullptr) {
3381             TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3382             parentSession->RemoveToastSession(persistentId);
3383         } else {
3384             TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3385         }
3386     }
3387     ret = sceneSession->Disconnect();
3388     sceneSession->ClearSpecificSessionCbMap();
3389     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3390         DestroySubSession(sceneSession);
3391         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3392         if (parentSession != nullptr) {
3393             TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3394             parentSession->RemoveSubSession(sceneSession->GetPersistentId());
3395         } else {
3396             TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3397         }
3398         DestroyUIServiceExtensionSubWindow(sceneSession);
3399     }
3400     {
3401         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3402         EraseSceneSessionAndMarkDirtyLocked(persistentId);
3403         systemTopSceneSessionMap_.erase(persistentId);
3404         nonSystemFloatSceneSessionMap_.erase(persistentId);
3405         UnregisterCreateSubSessionListener(persistentId);
3406     }
3407     ClearSpecificSessionRemoteObjectMap(persistentId);
3408     TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3409     return ret;
3410 }
3411 
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)3412 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
3413 {
3414     if (!sceneSession) {
3415         TLOGE(WmsLogTag::WMS_SUB,"sceneSession is null");
3416         return;
3417     }
3418     auto sessionProperty = sceneSession->GetSessionProperty();
3419     if (sessionProperty && sessionProperty->GetExtensionFlag() == true &&
3420         !sessionProperty->GetIsUIExtensionAbilityProcess()) {
3421         sceneSession->NotifyDestroy();
3422         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
3423             TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
3424         TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
3425             sceneSession->GetPersistentId(), errCode);
3426     }
3427 }
3428 
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3429 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3430 {
3431     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3432     auto task = [this, persistentId, callingPid]() {
3433         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3434         auto sceneSession = GetSceneSession(persistentId);
3435         if (sceneSession == nullptr) {
3436             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3437             return WSError::WS_ERROR_NULLPTR;
3438         }
3439 
3440         if (callingPid != sceneSession->GetCallingPid()) {
3441             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3442             return WSError::WS_ERROR_INVALID_PERMISSION;
3443         }
3444         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3445     };
3446 
3447     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3448 }
3449 
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)3450 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3451     const sptr<IRemoteObject>& callback)
3452 {
3453     if (callback == nullptr) {
3454         return WSError::WS_ERROR_NULLPTR;
3455     }
3456     const auto callingPid = IPCSkeleton::GetCallingRealPid();
3457     auto task = [this, persistentId, callingPid, callback]() {
3458         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3459         auto sceneSession = GetSceneSession(persistentId);
3460         if (sceneSession == nullptr) {
3461             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3462             return WSError::WS_ERROR_NULLPTR;
3463         }
3464 
3465         if (callingPid != sceneSession->GetCallingPid()) {
3466             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3467             return WSError::WS_ERROR_INVALID_PERMISSION;
3468         }
3469         sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3470         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3471     };
3472 
3473     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3474 }
3475 
GetWindowSceneConfig() const3476 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3477 {
3478     return appWindowSceneConfig_;
3479 }
3480 
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)3481 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3482 {
3483     auto task = [this, config]() {
3484         TLOGI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3485         rotateAnimationConfig_.duration_ = config.duration_;
3486     };
3487     taskScheduler_->PostAsyncTask(task, "UpdateRotateAnimationConfig");
3488 }
3489 
ProcessBackEvent()3490 WSError SceneSessionManager::ProcessBackEvent()
3491 {
3492     auto task = [this]() {
3493         auto session = GetSceneSession(focusedSessionId_);
3494         if (!session) {
3495             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId_);
3496             return WSError::WS_ERROR_INVALID_SESSION;
3497         }
3498         TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
3499             focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3500         if (needBlockNotifyFocusStatusUntilForeground_) {
3501             TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
3502             if (session->GetSessionInfo().abilityInfo != nullptr &&
3503                 session->GetSessionInfo().abilityInfo->unclearableMission) {
3504                 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3505                 return WSError::WS_OK;
3506             }
3507             session->RequestSessionBack(true);
3508             return WSError::WS_OK;
3509         }
3510         if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3511             rootSceneProcessBackEventFunc_();
3512         } else {
3513             session->ProcessBackEvent();
3514         }
3515         return WSError::WS_OK;
3516     };
3517 
3518     taskScheduler_->PostAsyncTask(task, __func__);
3519     return WSError::WS_OK;
3520 }
3521 
InitUserInfo(int32_t userId,std::string & fileDir)3522 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3523 {
3524     if (userId == DEFAULT_USERID || fileDir.empty()) {
3525         TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3526         return WSError::WS_DO_NOTHING;
3527     }
3528     TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3529     auto task = [this, userId, &fileDir]() {
3530         if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3531             TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3532         }
3533         if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3534             TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3535         }
3536         currentUserId_ = userId;
3537         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3538         AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3539         RegisterSecSurfaceInfoListener();
3540         return WSError::WS_OK;
3541     };
3542     return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3543 }
3544 
NotifySwitchingUser(const bool isUserActive)3545 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3546 {
3547     auto task = [this, isUserActive]() {
3548         TLOGI(WmsLogTag::WMS_MULTI_USER, "Notify switching user. IsUserActive=%{public}u, currentUserId=%{public}d",
3549             isUserActive, currentUserId_.load());
3550         isUserBackground_ = !isUserActive;
3551         SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3552         if (isUserActive) { // switch to current user
3553             SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3554             AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3555             // notify screenSessionManager to recover current user
3556             ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3557             FlushWindowInfoToMMI(true);
3558             NotifyAllAccessibilityInfo();
3559             rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3560             UpdatePrivateStateAndNotifyForAllScreens();
3561         } else { // switch to another user
3562             SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3563             rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3564         }
3565         return WSError::WS_OK;
3566     };
3567     taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3568 }
3569 
GetBundleManager()3570 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3571 {
3572     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3573     if (systemAbilityMgr == nullptr) {
3574         WLOGFE("Failed to get SystemAbilityManager.");
3575         return nullptr;
3576     }
3577 
3578     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3579     if (bmsObj == nullptr) {
3580         WLOGFE("Failed to get BundleManagerService.");
3581         return nullptr;
3582     }
3583 
3584     return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3585 }
3586 
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)3587 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3588     const AppExecFwk::AbilityInfo& abilityInfo)
3589 {
3590     auto context = rootSceneContextWeak_.lock();
3591     if (!context) {
3592         WLOGFE("context is nullptr.");
3593         return nullptr;
3594     }
3595     auto resourceMgr = context->GetResourceManager();
3596     if (!resourceMgr) {
3597         WLOGFE("resourceMgr is nullptr.");
3598         return nullptr;
3599     }
3600     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3601     if (!resConfig) {
3602         WLOGFE("resConfig is nullptr.");
3603         return nullptr;
3604     }
3605     resourceMgr->GetResConfig(*resConfig);
3606     resourceMgr = Global::Resource::CreateResourceManager(
3607         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3608     if (!resourceMgr) {
3609         WLOGFE("resourceMgr is nullptr.");
3610         return nullptr;
3611     }
3612     resourceMgr->UpdateResConfig(*resConfig);
3613 
3614     std::string loadPath;
3615     if (!abilityInfo.hapPath.empty()) { // zipped hap
3616         loadPath = abilityInfo.hapPath;
3617     } else {
3618         loadPath = abilityInfo.resourcePath;
3619     }
3620 
3621     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3622         WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3623     }
3624     return resourceMgr;
3625 }
3626 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)3627 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3628     std::string& path, uint32_t& bgColor)
3629 {
3630     auto resourceMgr = GetResourceManager(abilityInfo);
3631     if (!resourceMgr) {
3632         WLOGFE("resourceMgr is nullptr.");
3633         return false;
3634     }
3635 
3636     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3637         WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3638         return false;
3639     }
3640 
3641     if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3642         WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3643         return false;
3644     }
3645 
3646     if (!abilityInfo.hapPath.empty()) { // zipped hap
3647         auto pos = path.find_last_of('.');
3648         if (pos == std::string::npos) {
3649             WLOGFE("Format error, path %{private}s.", path.c_str());
3650             return false;
3651         }
3652         path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3653     }
3654     return true;
3655 }
3656 
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3657 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3658 {
3659     if (!bundleMgr_) {
3660         WLOGFE("bundleMgr_ is nullptr.");
3661         return;
3662     }
3663     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3664     if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3665         WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3666         return;
3667     }
3668     AAFwk::Want want;
3669     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3670     AppExecFwk::AbilityInfo abilityInfo;
3671     if (!bundleMgr_->QueryAbilityInfo(
3672         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3673         WLOGFE("Get ability info from BMS failed!");
3674         return;
3675     }
3676 
3677     if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3678         CacheStartingWindowInfo(abilityInfo, path, bgColor);
3679     }
3680     WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3681         abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3682 }
3683 
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3684 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3685     const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3686 {
3687     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3688     std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3689     auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3690     if (iter == startingWindowMap_.end()) {
3691         return false;
3692     }
3693     auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3694     const auto& infoMap = iter->second;
3695     auto infoMapIter = infoMap.find(key);
3696     if (infoMapIter == infoMap.end()) {
3697         return false;
3698     }
3699     path = infoMapIter->second.startingWindowIconPath_;
3700     bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3701     return true;
3702 }
3703 
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)3704 void SceneSessionManager::CacheStartingWindowInfo(
3705     const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3706 {
3707     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3708     auto key = abilityInfo.moduleName + abilityInfo.name;
3709     StartingWindowInfo info = {
3710         .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3711         .startingWindowIconId_ = abilityInfo.startWindowIconId,
3712         .startingWindowBackgroundColor_ = bgColor,
3713         .startingWindowIconPath_ = path,
3714     };
3715     std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3716     auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3717     if (iter != startingWindowMap_.end()) {
3718         auto& infoMap = iter->second;
3719         infoMap.emplace(key, info);
3720         return;
3721     }
3722     if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3723         startingWindowMap_.erase(startingWindowMap_.begin());
3724     }
3725     std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3726     startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3727 }
3728 
OnBundleUpdated(const std::string & bundleName,int userId)3729 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3730 {
3731     taskScheduler_->PostAsyncTask([this, bundleName]() {
3732         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3733         auto iter = startingWindowMap_.find(bundleName);
3734         if (iter != startingWindowMap_.end()) {
3735             startingWindowMap_.erase(iter);
3736         }
3737     },
3738         "OnBundleUpdated");
3739 }
3740 
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3741 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3742 {
3743     taskScheduler_->PostAsyncTask([this]() {
3744         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3745         startingWindowMap_.clear();
3746     },
3747         "OnConfigurationUpdated");
3748 }
3749 
FillSessionInfo(sptr<SceneSession> & sceneSession)3750 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3751 {
3752     auto sessionInfo = sceneSession->GetSessionInfo();
3753     if (sessionInfo.bundleName_.empty()) {
3754         WLOGFE("bundleName_ is empty");
3755         return;
3756     }
3757     if (sessionInfo.isSystem_) {
3758         WLOGFD("is system scene!");
3759         return;
3760     }
3761     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3762         sessionInfo.moduleName_);
3763     if (abilityInfo == nullptr) {
3764         WLOGFE("abilityInfo is nullptr!");
3765         return;
3766     }
3767     sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
3768     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3769     sceneSession->SetSessionInfoTime(GetCurrentTime());
3770     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3771         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3772     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3773         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3774     }
3775     TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3776         "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3777         abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3778         abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3779 }
3780 
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)3781 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3782     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3783 {
3784     if (!bundleMgr_) {
3785         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3786         return nullptr;
3787     }
3788     AAFwk::Want want;
3789     want.SetElementName("", bundleName, abilityName, moduleName);
3790     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3791     if (abilityInfo == nullptr) {
3792         WLOGFE("abilityInfo is nullptr!");
3793         return nullptr;
3794     }
3795     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3796         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3797         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3798     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
3799     if (!ret) {
3800         WLOGFE("Get ability info from BMS failed!");
3801         return nullptr;
3802     }
3803     return abilityInfo;
3804 }
3805 
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)3806 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
3807     uint32_t& topWinId, uint32_t& zOrder)
3808 {
3809     const auto& subVec = session->GetSubSession();
3810     for (const auto& subSession : subVec) {
3811         if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
3812             TLOGW(WmsLogTag::WMS_SUB,
3813                 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
3814             continue;
3815         }
3816         if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3817              subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
3818             subSession->GetZOrder() > zOrder) {
3819             topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
3820             zOrder = subSession->GetZOrder();
3821             TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
3822                 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
3823         }
3824         if (subSession->GetSubSession().size() > 0) {
3825             GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
3826         }
3827     }
3828 }
3829 
3830 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)3831 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
3832 {
3833     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3834     auto task = [this, mainWinId, &topWinId, callingPid]() {
3835         const auto& mainSession = GetSceneSession(mainWinId);
3836         if (mainSession == nullptr) {
3837             return WMError::WM_ERROR_INVALID_WINDOW;
3838         }
3839 
3840         if (callingPid != mainSession->GetCallingPid()) {
3841             WLOGFE("Permission denied, not destroy by the same process");
3842             return WMError::WM_ERROR_INVALID_PERMISSION;
3843         }
3844         uint32_t zOrder = mainSession->GetZOrder();
3845         topWinId = mainWinId;
3846         GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
3847         TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
3848             "zOrder: %{public}d", mainWinId, topWinId, zOrder);
3849         return WMError::WM_OK;
3850     };
3851 
3852     if (!Session::IsScbCoreEnabled()) {
3853         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3854     }
3855     bool postNow = false;
3856     auto mainSession = GetSceneSession(mainWinId);
3857     if (mainSession != nullptr) {
3858         postNow = !(mainSession->GetUIStateDirty());
3859     }
3860     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
3861     if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
3862         taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
3863         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3864     }
3865     TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
3866     {
3867         std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
3868         if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
3869             std::cv_status::timeout) {
3870             TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
3871         }
3872     }
3873     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3874 }
3875 
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)3876 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
3877     int32_t windowId, int32_t& mainWindowId)
3878 {
3879     auto iter = sceneSessionMap.find(windowId);
3880     if (iter == sceneSessionMap.end()) {
3881         TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
3882         return WMError::WM_ERROR_NULLPTR;
3883     }
3884     sptr<SceneSession> sceneSession = iter->second;
3885     if (sceneSession == nullptr) {
3886         TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
3887         return WMError::WM_ERROR_NULLPTR;
3888     }
3889     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3890         mainWindowId = sceneSession->GetPersistentId();
3891         return WMError::WM_OK;
3892     }
3893     if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3894         WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
3895         return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
3896     }
3897     // not sub window, dialog, return invalid id
3898     mainWindowId = INVALID_SESSION_ID;
3899     return WMError::WM_OK;
3900 }
3901 
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)3902 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
3903 {
3904     if (windowId == INVALID_SESSION_ID) {
3905         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3906         return WMError::WM_ERROR_INVALID_PARAM;
3907     }
3908     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3909     return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
3910 }
3911 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3912 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
3913     const sptr<SceneSession>& sceneSession)
3914 {
3915     auto systemBarProperties = property->GetSystemBarProperty();
3916     for (auto iter : systemBarProperties) {
3917         if (iter.first == type) {
3918             sceneSession->SetSystemBarProperty(iter.first, iter.second);
3919             TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
3920                 static_cast<int32_t>(iter.first), iter.second.enable_);
3921         }
3922     }
3923     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3924 }
3925 
3926 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3927 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
3928     const sptr<SceneSession>& sceneSession)
3929 {
3930     if (!SessionPermission::IsSystemCalling()) {
3931         TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
3932         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3933     }
3934 
3935     sceneSession->SetTopmost(property->IsTopmost());
3936     return WMError::WM_OK;
3937 }
3938 
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3939 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3940     const sptr<SceneSession>& sceneSession)
3941 {
3942     bool isPcWindow = false;
3943     IsPcWindow(isPcWindow);
3944     if (isPcWindow) {
3945         TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
3946         return;
3947     }
3948     auto propertyOld = sceneSession->GetSessionProperty();
3949     if (propertyOld == nullptr) {
3950         TLOGI(WmsLogTag::DEFAULT, "session property null");
3951         return;
3952     }
3953 
3954     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
3955     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
3956     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
3957         TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
3958         return;
3959     }
3960 
3961     if (IsSessionVisibleForeground(sceneSession)) {
3962         if (hideNonSystemFloatingWindowsOld) {
3963             UpdateForceHideState(sceneSession, propertyOld, false);
3964         } else {
3965             UpdateForceHideState(sceneSession, property, true);
3966         }
3967     }
3968 }
3969 
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)3970 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
3971     const sptr<WindowSessionProperty>& property, bool add)
3972 {
3973     if (systemConfig_.uiType_ == UI_TYPE_PC) {
3974         TLOGI(WmsLogTag::DEFAULT, "IsPcWindow, ineffective");
3975         return;
3976     }
3977     if (property == nullptr) {
3978         WLOGFD("property is nullptr");
3979         return;
3980     }
3981     auto persistentId = sceneSession->GetPersistentId();
3982     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
3983     bool notifyAll = false;
3984     if (add) {
3985         if (property->GetHideNonSystemFloatingWindows()) {
3986             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
3987             notifyAll = !forceHideFloatOld;
3988         } else if (property->IsFloatingWindowAppType()) {
3989             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
3990             if (forceHideFloatOld) {
3991                 sceneSession->NotifyForceHideChange(true);
3992             }
3993         }
3994     } else {
3995         if (property->GetHideNonSystemFloatingWindows()) {
3996             systemTopSceneSessionMap_.erase(persistentId);
3997             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
3998         } else if (property->IsFloatingWindowAppType()) {
3999             nonSystemFloatSceneSessionMap_.erase(persistentId);
4000             if (property->GetForceHide()) {
4001                 sceneSession->NotifyForceHideChange(false);
4002             }
4003         }
4004     }
4005     if (notifyAll) {
4006         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
4007         for (const auto& item : nonSystemFloatSceneSessionMap_) {
4008             auto forceHideSceneSession = item.second;
4009             auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
4010             if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
4011                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
4012             }
4013         }
4014     }
4015 }
4016 
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)4017 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
4018 {
4019 #ifdef POWER_MANAGER_ENABLE
4020     auto task = [this, sceneSession]() {
4021         if (sceneSession == nullptr) {
4022             WLOGFE("session is invalid");
4023             return;
4024         }
4025         WLOGFD("Win: %{public}s, is turn on%{public}d",
4026             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4027         std::string identity = IPCSkeleton::ResetCallingIdentity();
4028         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
4029             WLOGI("turn screen on");
4030             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4031         }
4032         // set ipc identity to raw
4033         IPCSkeleton::SetCallingIdentity(identity);
4034     };
4035     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
4036 
4037 #else
4038     WLOGFD("Can not found the sub system of PowerMgr");
4039 #endif
4040 }
4041 
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)4042 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
4043 {
4044 #ifdef POWER_MANAGER_ENABLE
4045     wptr<SceneSession> weakSceneSession(sceneSession);
4046     auto task = [this, weakSceneSession, requireLock]() {
4047         auto scnSession = weakSceneSession.promote();
4048         if (scnSession == nullptr) {
4049             WLOGFE("session is invalid");
4050             return;
4051         }
4052         if (requireLock && scnSession->keepScreenLock_ == nullptr) {
4053             // reset ipc identity
4054             std::string identity = IPCSkeleton::ResetCallingIdentity();
4055             scnSession->keepScreenLock_ =
4056                 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
4057                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
4058             // set ipc identity to raw
4059             IPCSkeleton::SetCallingIdentity(identity);
4060         }
4061         if (scnSession->keepScreenLock_ == nullptr) {
4062             return;
4063         }
4064         bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession);
4065         TLOGNI(WmsLogTag::DEFAULT, "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d]",
4066             scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
4067             scnSession->IsVisible(), requireLock, shouldLock);
4068         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
4069         ErrCode res;
4070         std::string identity = IPCSkeleton::ResetCallingIdentity();
4071         if (shouldLock) {
4072             res = scnSession->keepScreenLock_->Lock();
4073         } else {
4074             res = scnSession->keepScreenLock_->UnLock();
4075         }
4076         // set ipc identity to raw
4077         IPCSkeleton::SetCallingIdentity(identity);
4078         if (res != ERR_OK) {
4079             WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
4080                 requireLock, res);
4081         }
4082     };
4083     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
4084 #else
4085     WLOGFD("Can not found the sub system of PowerMgr");
4086 #endif
4087 }
4088 
NotifyVisibleChange(int32_t persistentId)4089 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
4090 {
4091     auto sceneSession = GetSceneSession(persistentId);
4092     if (sceneSession == nullptr) {
4093         return false;
4094     }
4095     HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
4096     ProcessWindowModeType();
4097     return true;
4098 }
4099 
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)4100 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
4101 {
4102 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
4103     if (GetDisplayBrightness() != brightness &&
4104         GetFocusedSessionId() == sceneSession->GetPersistentId()) {
4105         PostBrightnessTask(brightness);
4106     }
4107 #else
4108     WLOGFD("Can not found the sub system of DisplayPowerMgr");
4109 #endif
4110     brightnessSessionId_ = sceneSession->GetPersistentId();
4111     return WSError::WS_OK;
4112 }
4113 
PostBrightnessTask(float brightness)4114 void SceneSessionManager::PostBrightnessTask(float brightness)
4115 {
4116     bool postTaskRet = true;
4117     bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4118     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4119         if (!isPC) {
4120             auto task = [] {
4121                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4122             };
4123             postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
4124         }
4125         SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4126     } else {
4127         auto task = [brightness, isPC] {
4128             if (isPC) {
4129                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4130                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4131             } else {
4132                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4133                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4134             }
4135         };
4136         postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
4137         SetDisplayBrightness(brightness);
4138     }
4139     if (!postTaskRet) {
4140         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
4141     }
4142 }
4143 
UpdateBrightness(int32_t persistentId)4144 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
4145 {
4146     auto sceneSession = GetSceneSession(persistentId);
4147     if (sceneSession == nullptr) {
4148         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4149         return WSError::WS_ERROR_NULLPTR;
4150     }
4151     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4152             sceneSession->GetSessionInfo().isSystem_)) {
4153         TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
4154         return WSError::WS_DO_NOTHING;
4155     }
4156     auto brightness = sceneSession->GetBrightness();
4157     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
4158     bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4159     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4160         if (GetDisplayBrightness() != brightness) {
4161             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
4162             if (!isPC) {
4163                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4164             }
4165             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4166         }
4167         brightnessSessionId_ = INVALID_WINDOW_ID;
4168     } else {
4169         if (GetDisplayBrightness() != brightness) {
4170             TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
4171             if (isPC) {
4172                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4173                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4174             } else {
4175                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4176                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4177             }
4178             SetDisplayBrightness(brightness);
4179         }
4180         brightnessSessionId_ = sceneSession->GetPersistentId();
4181     }
4182     return WSError::WS_OK;
4183 }
4184 
GetCurrentUserId() const4185 int32_t SceneSessionManager::GetCurrentUserId() const
4186 {
4187     return currentUserId_;
4188 }
4189 
SetDisplayBrightness(float brightness)4190 void SceneSessionManager::SetDisplayBrightness(float brightness)
4191 {
4192     displayBrightness_ = brightness;
4193 }
4194 
GetDisplayBrightness() const4195 float SceneSessionManager::GetDisplayBrightness() const
4196 {
4197     return displayBrightness_;
4198 }
4199 
SetGestureNavigaionEnabled(bool enable)4200 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
4201 {
4202     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4203         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
4204         return WMError::WM_ERROR_NOT_SYSTEM_APP;
4205     }
4206     std::string callerBundleName = SessionPermission::GetCallingBundleName();
4207     TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
4208     auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
4209         SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
4210         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
4211             WLOGFE("callback func is null");
4212             return WMError::WM_OK;
4213         }
4214         if (gestureNavigationEnabledChangeFunc_) {
4215             gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
4216         }
4217         if (statusBarEnabledChangeFunc_) {
4218             statusBarEnabledChangeFunc_(enable, bundleName);
4219         }
4220         return WMError::WM_OK;
4221     };
4222     return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
4223 }
4224 
SetFocusedSessionId(int32_t persistentId)4225 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
4226 {
4227     if (focusedSessionId_ == persistentId) {
4228         WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
4229         return WSError::WS_DO_NOTHING;
4230     }
4231     lastFocusedSessionId_ = focusedSessionId_;
4232     focusedSessionId_ = persistentId;
4233     return WSError::WS_OK;
4234 }
4235 
GetFocusedSessionId() const4236 int32_t SceneSessionManager::GetFocusedSessionId() const
4237 {
4238     return focusedSessionId_;
4239 }
4240 
GetFocusWindowInfo(FocusChangeInfo & focusInfo)4241 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
4242 {
4243     if (!SessionPermission::IsSACalling()) {
4244         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
4245         return;
4246     }
4247     auto task = [this, &focusInfo] {
4248         if (auto sceneSession = GetSceneSession(focusedSessionId_)) {
4249             TLOGND(WmsLogTag::WMS_FOCUS, "Get focus session info success");
4250             focusInfo.windowId_ = sceneSession->GetWindowId();
4251             focusInfo.displayId_ = static_cast<DisplayId>(0);
4252             focusInfo.pid_ = sceneSession->GetCallingPid();
4253             focusInfo.uid_ = sceneSession->GetCallingUid();
4254             focusInfo.windowType_ = sceneSession->GetWindowType();
4255             focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
4256             return WSError::WS_OK;
4257         }
4258         return WSError::WS_ERROR_DESTROYED_OBJECT;
4259     };
4260     taskScheduler_->PostSyncTask(task, __func__);
4261 }
4262 
IsValidDigitString(const std::string & windowIdStr)4263 static bool IsValidDigitString(const std::string& windowIdStr)
4264 {
4265     if (windowIdStr.empty()) {
4266         return false;
4267     }
4268     for (char ch : windowIdStr) {
4269         if ((ch >= '0' && ch <= '9')) {
4270             continue;
4271         }
4272         WLOGFE("invalid window id");
4273         return false;
4274     }
4275     return true;
4276 }
4277 
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)4278 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
4279 {
4280     if (sceneSession == nullptr) {
4281         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
4282         return;
4283     }
4284     const char* const where = __func__;
4285     sceneSession->SetSessionExceptionListener([this, where](
4286         const SessionInfo& info, bool needRemoveSession = false, bool startFail = false) {
4287         auto task = [this, info, where] {
4288             auto scnSession = GetSceneSession(info.persistentId_);
4289             if (scnSession == nullptr) {
4290                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
4291                 return;
4292             }
4293             if (listenerController_ == nullptr) {
4294                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s listenerController_ is nullptr", where);
4295                 return;
4296             }
4297             if (scnSession->GetSessionInfo().isSystem_) {
4298                 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where,
4299                     scnSession->GetPersistentId());
4300                 return;
4301             }
4302             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
4303                 where, info.errorCode, info.persistentId_);
4304             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
4305                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
4306                 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
4307                     "or foreground timeout, id: %{public}d", info.persistentId_);
4308                 listenerController_->NotifySessionClosed(info.persistentId_);
4309             }
4310         };
4311         taskScheduler_->PostVoidSyncTask(task, "sessionException");
4312     }, false);
4313     TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
4314 }
4315 
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)4316 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
4317 {
4318     if (sceneSession == nullptr) {
4319         WLOGFE("session is nullptr");
4320         return;
4321     }
4322     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
4323         auto sceneSession = GetSceneSession(persistentId);
4324         if (sceneSession == nullptr) {
4325             WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
4326             return;
4327         }
4328         if (sceneSession->GetSessionInfo().isSystem_) {
4329             WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
4330             return;
4331         }
4332         auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
4333         if (abilityInfoPtr == nullptr) {
4334             WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
4335             return;
4336         }
4337         if (listenerController_ == nullptr) {
4338             WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
4339             return;
4340         }
4341         if (!abilityInfoPtr->excludeFromMissions) {
4342             listenerController_->NotifySessionSnapshotChanged(persistentId);
4343         }
4344     };
4345     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
4346     WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
4347 }
4348 
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)4349 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
4350 {
4351     if (sceneSession == nullptr) {
4352         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
4353         return;
4354     }
4355     AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
4356         config.duration_ = rotateAnimationConfig_.duration_;
4357     };
4358     sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
4359     TLOGD(WmsLogTag::DEFAULT, "Register acquire Rotate Animation config success, id: %{public}d",
4360         sceneSession->GetPersistentId());
4361 }
4362 
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)4363 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
4364 {
4365     if (scnSession == nullptr) {
4366         WLOGFW("NotifySessionForCallback, scnSession is nullptr");
4367         return;
4368     }
4369     if (scnSession->GetSessionInfo().isSystem_) {
4370         WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
4371         return;
4372     }
4373     WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
4374            static_cast<uint32_t>(needRemoveSession));
4375     if (scnSession->GetSessionInfo().appIndex_ != 0) {
4376         WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
4377                scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
4378         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4379         return;
4380     }
4381     if (needRemoveSession) {
4382         WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
4383         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4384         return;
4385     }
4386     if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
4387         WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
4388     } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4389                (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4390         WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4391             scnSession->GetPersistentId());
4392         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4393         return;
4394     }
4395     WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
4396     listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
4397 }
4398 
NotifyWindowInfoChangeFromSession(int32_t persistentId)4399 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4400 {
4401     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4402     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4403     if (sceneSession == nullptr) {
4404         WLOGFE("sceneSession nullptr");
4405         return;
4406     }
4407 
4408     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4409 }
4410 
IsSessionVisible(const sptr<SceneSession> & session)4411 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4412 {
4413     if (session == nullptr) {
4414         return false;
4415     }
4416     if (Session::IsScbCoreEnabled()) {
4417         return session->IsVisible();
4418     }
4419     const auto& state = session->GetSessionState();
4420     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4421         const auto& parentSceneSession = session->GetParentSession();
4422         if (parentSceneSession == nullptr) {
4423             WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
4424             return false;
4425         }
4426         const auto& parentState = parentSceneSession->GetSessionState();
4427         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4428             if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
4429                 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
4430                 return false;
4431             }
4432             WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4433             return true;
4434         }
4435         WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4436         return false;
4437     }
4438 
4439     if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
4440         WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
4441         return true;
4442     }
4443     WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
4444     return false;
4445 }
4446 
IsSessionVisibleForeground(const sptr<SceneSession> & session)4447 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4448 {
4449     if (session == nullptr) {
4450         return false;
4451     }
4452     if (Session::IsScbCoreEnabled()) {
4453         return session->IsVisibleForeground();
4454     }
4455     return IsSessionVisible(session);
4456 }
4457 
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)4458 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4459 {
4460     if (session == nullptr) {
4461         return;
4462     }
4463     int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4464     WSRect rect = session->GetSessionRect();
4465     std::string sName;
4466     if (session->GetSessionInfo().isSystem_) {
4467         sName = session->GetSessionInfo().abilityName_;
4468     } else {
4469         sName = session->GetWindowName();
4470     }
4471     uint32_t flag = 0;
4472     uint64_t displayId = INVALID_SCREEN_ID;
4473     auto sessionProperty = session->GetSessionProperty();
4474     if (sessionProperty) {
4475         flag = sessionProperty->GetWindowFlags();
4476         displayId = sessionProperty->GetDisplayId();
4477     }
4478     uint32_t orientation = 0;
4479     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4480         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4481     // std::setw is used to set the output width and different width values are set to keep the format aligned.
4482     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4483         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4484         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4485         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4486         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4487         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4488         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4489         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4490         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4491         << "[ "
4492         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4493         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4494         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4495         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4496         << "]"
4497         << " [ "
4498         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4499         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4500         << "]"
4501         << " [ "
4502         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4503         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4504         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4505         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4506         << "]"
4507         << std::endl;
4508 }
4509 
GetAllSessionDumpInfo(std::string & dumpInfo)4510 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4511 {
4512     int32_t screenGroupId = 0;
4513     std::ostringstream oss;
4514     oss << "-------------------------------------ScreenGroup " << screenGroupId
4515         << "-------------------------------------" << std::endl;
4516     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
4517         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]"
4518         << std::endl;
4519 
4520     std::vector<sptr<SceneSession>> allSession;
4521     std::vector<sptr<SceneSession>> backgroundSession;
4522     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4523     {
4524         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4525         sceneSessionMapCopy = sceneSessionMap_;
4526     }
4527     for (const auto& elem : sceneSessionMapCopy) {
4528         auto curSession = elem.second;
4529         if (curSession == nullptr || (!curSession->GetSessionInfo().isSystem_ && (curSession->GetSessionState() <
4530             SessionState::STATE_FOREGROUND || curSession->GetSessionState() > SessionState::STATE_BACKGROUND))) {
4531             WLOGFW("Session is nullptr or session state is invalid, id: %{public}d, state: %{public}u",
4532                 curSession->GetPersistentId(), curSession->GetSessionState());
4533             continue;
4534         }
4535         if (IsSessionVisibleForeground(curSession)) {
4536             allSession.push_back(curSession);
4537         } else {
4538             backgroundSession.push_back(curSession);
4539         }
4540     }
4541     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4542     uint32_t count = 0;
4543     for (const auto& session : allSession) {
4544         if (session == nullptr) {
4545             continue;
4546         }
4547         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4548             oss << "---------------------------------------------------------------------------------------"
4549                 << std::endl;
4550         }
4551         DumpSessionInfo(session, oss);
4552         count++;
4553     }
4554     oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4555     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4556     dumpInfo.append(oss.str());
4557     return WSError::WS_OK;
4558 }
4559 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)4560 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4561 {
4562     dumpRootSceneFunc_ = func;
4563 }
4564 
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)4565 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4566     const std::vector<std::string>& params, std::string& dumpInfo)
4567 {
4568     std::vector<std::string> resetParams;
4569     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4570     if (resetParams.empty()) {
4571         WLOGI("do not dump ui info");
4572         return;
4573     }
4574 
4575     if (!session->GetSessionInfo().isSystem_) {
4576         WLOGFI("Dump normal session, not system");
4577         dumpInfoFuture_.ResetLock({});
4578         session->DumpSessionElementInfo(resetParams);
4579         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4580         for (auto& info: infos) {
4581             dumpInfo.append(info).append("\n");
4582         }
4583     } else {
4584         WLOGFI("Dump system session");
4585         std::vector<std::string> infos;
4586         dumpRootSceneFunc_(resetParams, infos);
4587         for (auto& info: infos) {
4588             dumpInfo.append(info).append("\n");
4589         }
4590     }
4591 }
4592 
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)4593 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4594     const std::string& strId)
4595 {
4596     uint64_t persistentId = std::stoull(strId);
4597     auto session = GetSceneSession(persistentId);
4598     if (session == nullptr) {
4599         return WSError::WS_ERROR_INVALID_PARAM;
4600     }
4601     auto sessionProperty = session->GetSessionProperty();
4602     if (sessionProperty == nullptr) {
4603         return WSError::WS_ERROR_INVALID_PARAM;
4604     }
4605 
4606     WSRect rect = session->GetSessionRect();
4607     std::string isVisible = session->IsVisible() ? "true" : "false";
4608     std::string focusable = session->GetFocusable() ? "true" : "false";
4609     std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4610     bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4611     std::string isPrivacyMode = privacyMode ? "true" : "false";
4612     bool isFirstFrameAvailable = true;
4613     std::ostringstream oss;
4614     oss << "WindowName: " << session->GetWindowName()  << std::endl;
4615     oss << "DisplayId: " << 0 << std::endl;
4616     oss << "WinId: " << session->GetPersistentId() << std::endl;
4617     oss << "Pid: " << session->GetCallingPid() << std::endl;
4618     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4619     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4620     oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4621     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4622     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4623     oss << "IsVisible: " << isVisible << std::endl;
4624     oss << "Focusable: "  << focusable << std::endl;
4625     oss << "DecoStatus: "  << decoStatus << std::endl;
4626     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
4627     oss << "WindowRect: " << "[ "
4628         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4629         << " ]" << std::endl;
4630     oss << "scaleX: " << session->GetScaleX() << std::endl;
4631     oss << "scaleY: " << session->GetScaleY() << std::endl;
4632     oss << "Offset: " << "[ "
4633         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4634     oss << "Scale: " << "[ "
4635         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4636         << session->GetPivotX() << ", " << session->GetPivotY()
4637         << " ]" << std::endl;
4638     dumpInfo.append(oss.str());
4639 
4640     DumpSessionElementInfo(session, params, dumpInfo);
4641     return WSError::WS_OK;
4642 }
4643 
GetSCBDebugDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params)4644 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params)
4645 {
4646     std::string cmd = ScbDumpSubscriber::JoinCommands(params, params.size());
4647 
4648     // publish data
4649     bool ret = eventHandler_->PostSyncTask([this, cmd] { return g_scbSubscriber->Publish(cmd); }, "PublishSCBDumper");
4650     if (!ret) {
4651         return WSError::WS_ERROR_INVALID_OPERATION;
4652     }
4653 
4654     // get response event
4655     auto task = [this, &dumpInfo]() {
4656         dumpInfo.append(g_scbSubscriber->GetDebugDumpInfo(WAIT_TIME));
4657         return WSError::WS_OK;
4658     };
4659     eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4660 
4661     return WSError::WS_OK;
4662 }
4663 
NotifyDumpInfoResult(const std::vector<std::string> & info)4664 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4665 {
4666     dumpInfoFuture_.SetValue(info);
4667     WLOGFD("NotifyDumpInfoResult");
4668 }
4669 
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)4670 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4671 {
4672     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4673         WLOGFE("GetSessionDumpInfo permission denied!");
4674         return WSError::WS_ERROR_INVALID_PERMISSION;
4675     }
4676 
4677     if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4678         return GetAllSessionDumpInfo(dumpInfo);
4679     }
4680     if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4681         return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4682     }
4683     if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2:params num
4684         return GetSCBDebugDumpInfo(dumpInfo, params);
4685     }
4686     if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
4687         return GetTotalUITreeInfo(dumpInfo);
4688     }
4689     return WSError::WS_ERROR_INVALID_OPERATION;
4690 }
4691 
GetTotalUITreeInfo(std::string & dumpInfo)4692 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
4693 {
4694     TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4695     if (dumpUITreeFunc_) {
4696         dumpUITreeFunc_(dumpInfo);
4697     } else {
4698         TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4699     }
4700     return WSError::WS_OK;
4701 }
4702 
SetDumpUITreeFunc(const DumpUITreeFunc & func)4703 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4704 {
4705     dumpUITreeFunc_ = func;
4706 }
4707 
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)4708 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
4709 {
4710     onFlushUIParamsFunc_ = std::move(func);
4711 }
4712 
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)4713 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
4714 {
4715     isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
4716 }
4717 
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)4718 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
4719 {
4720     taskScheduler_->PostAsyncTask([this, displayId, visible] {
4721         statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
4722         TLOGNI(WmsLogTag::WMS_IMMS,
4723             "set default visibility on display: %{public}" PRIu64 " visible: %{public}d", displayId, visible);
4724     }, __func__);
4725 }
4726 
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)4727 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
4728 {
4729     return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
4730            statusBarDefaultVisibilityPerDisplay_[displayId] : true;
4731 }
4732 
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)4733 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4734 {
4735     // notify RS
4736     WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4737         " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4738         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4739         sceneSession->GetSessionInfo().bundleName_.c_str(),
4740         sceneSession->GetSessionInfo().abilityName_.c_str(),
4741         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4742     uint64_t focusNodeId = 0; // 0 means invalid
4743     if (sceneSession->GetSurfaceNode() == nullptr) {
4744         WLOGFW("focused window surfaceNode is null");
4745     } else {
4746         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4747     }
4748     FocusAppInfo appInfo = {
4749         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4750         sceneSession->GetSessionInfo().bundleName_,
4751         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4752     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4753 }
4754 
4755 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4756 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4757 {
4758     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4759     {
4760         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4761         for (auto& iter : sceneSessionMap_) {
4762             ret.push_back(iter);
4763         }
4764     }
4765     std::sort(ret.begin(), ret.end(), cmp);
4766     return ret;
4767 }
4768 
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)4769 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4770 {
4771     if (isFromTopToBottom) {
4772         TraverseSessionTreeFromTopToBottom(func);
4773     } else {
4774         TraverseSessionTreeFromBottomToTop(func);
4775     }
4776     return;
4777 }
4778 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4779 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4780 {
4781     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4782         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4783         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4784         return lhsZOrder < rhsZOrder;
4785     };
4786     auto sceneSessionVector = GetSceneSessionVector(cmp);
4787 
4788     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
4789         auto session = iter->second;
4790         if (session == nullptr) {
4791             WLOGFE("session is nullptr");
4792             continue;
4793         }
4794         if (func(session)) {
4795             return;
4796         }
4797     }
4798     return;
4799 }
4800 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)4801 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
4802 {
4803     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4804     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4805         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4806         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4807         return lhsZOrder < rhsZOrder;
4808     };
4809     auto sceneSessionVector = GetSceneSessionVector(cmp);
4810     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
4811     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
4812         auto session = iter->second;
4813         if (session == nullptr) {
4814             WLOGFE("session is nullptr");
4815             continue;
4816         }
4817         if (func(session)) {
4818             return;
4819         }
4820     }
4821     return;
4822 }
4823 
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4824 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
4825     FocusChangeReason reason)
4826 {
4827     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4828     auto sceneSession = GetSceneSession(persistentId);
4829     if (sceneSession == nullptr) {
4830         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
4831         return WMError::WM_ERROR_NULLPTR;
4832     }
4833     int32_t callingPid = IPCSkeleton::GetCallingPid();
4834     if (callingPid != sceneSession->GetCallingPid() &&
4835         !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
4836         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
4837         return WMError::WM_ERROR_INVALID_CALLING;
4838     }
4839     auto task = [this, persistentId, isFocused, byForeground, reason]() {
4840         if (isFocused) {
4841             RequestSessionFocus(persistentId, byForeground, reason);
4842         } else {
4843             RequestSessionUnfocus(persistentId, reason);
4844         }
4845     };
4846     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
4847     focusChangeReason_ = reason;
4848     return WMError::WM_OK;
4849 }
4850 
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4851 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
4852     FocusChangeReason reason)
4853 {
4854     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4855     auto task = [this, persistentId, isFocused, byForeground, reason]() {
4856         if (isFocused) {
4857             if (reason == FocusChangeReason::FOREGROUND) {
4858                 RequestSessionFocusImmediately(persistentId);
4859                 return;
4860             }
4861             if (reason == FocusChangeReason::MOVE_UP) {
4862                 auto session = GetSceneSession(persistentId);
4863                 if (session && !session->IsFocused()) {
4864                     PostProcessFocusState state = { true, true, reason };
4865                     session->SetPostProcessFocusState(state);
4866                 }
4867                 return;
4868             }
4869             // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
4870             if (reason == FocusChangeReason::CLICK) {
4871                 return;
4872             }
4873             if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
4874                 auto session = GetSceneSession(persistentId);
4875                 if (session && !session->IsFocused()) {
4876                     PostProcessFocusState state = { true, true, reason };
4877                     session->SetPostProcessFocusState(state);
4878                 }
4879             }
4880         } else {
4881             RequestSessionUnfocus(persistentId, reason);
4882         }
4883     };
4884     taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
4885     return WMError::WM_OK;
4886 }
4887 
RequestAllAppSessionUnfocus()4888 void SceneSessionManager::RequestAllAppSessionUnfocus()
4889 {
4890     auto task = [this]() {
4891         RequestAllAppSessionUnfocusInner();
4892     };
4893     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
4894     return;
4895 }
4896 
4897 /**
4898  * request focus and ignore its state
4899  * only used when app main window start before foreground
4900 */
RequestSessionFocusImmediately(int32_t persistentId)4901 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
4902 {
4903     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
4904     // base block
4905     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4906     if (basicCheckRet != WSError::WS_OK) {
4907         return basicCheckRet;
4908     }
4909     auto sceneSession = GetSceneSession(persistentId);
4910     if (sceneSession == nullptr) {
4911         WLOGFE("[WMSComm]session is nullptr");
4912         return WSError::WS_ERROR_INVALID_SESSION;
4913     }
4914     if (!sceneSession->GetFocusable()) {
4915         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
4916         return WSError::WS_DO_NOTHING;
4917     }
4918     if (!sceneSession->IsFocusedOnShow()) {
4919         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4920         return WSError::WS_DO_NOTHING;
4921     }
4922 
4923     // specific block
4924     FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
4925     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
4926     if (specificCheckRet != WSError::WS_OK) {
4927         return specificCheckRet;
4928     }
4929 
4930     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4931     if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
4932         needBlockNotifyFocusStatusUntilForeground_ = true;
4933     }
4934     ShiftFocus(sceneSession, reason);
4935     return WSError::WS_OK;
4936 }
4937 
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)4938 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
4939 {
4940     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
4941         persistentId, byForeground, reason);
4942     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4943     if (basicCheckRet != WSError::WS_OK) {
4944         return basicCheckRet;
4945     }
4946     auto sceneSession = GetSceneSession(persistentId);
4947     if (sceneSession == nullptr) {
4948         WLOGFE("[WMSComm]session is nullptr");
4949         return WSError::WS_ERROR_INVALID_SESSION;
4950     }
4951     if (!sceneSession->GetFocusable() || !IsSessionVisibleForeground(sceneSession)) {
4952         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
4953         return WSError::WS_DO_NOTHING;
4954     }
4955     if (!sceneSession->IsFocusedOnShow()) {
4956         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4957         return WSError::WS_DO_NOTHING;
4958     }
4959     if (!sceneSession->IsFocusableOnShow() &&
4960         (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
4961         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
4962         return WSError::WS_DO_NOTHING;
4963     }
4964 
4965     // subwindow/dialog state block
4966     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4967         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4968         GetSceneSession(sceneSession->GetParentPersistentId()) &&
4969         !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
4970             TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
4971                 sceneSession->GetParentPersistentId());
4972             return WSError::WS_DO_NOTHING;
4973     }
4974     // specific block
4975     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
4976     if (specificCheckRet != WSError::WS_OK) {
4977         return specificCheckRet;
4978     }
4979 
4980     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4981     needBlockNotifyFocusStatusUntilForeground_ = false;
4982     ShiftFocus(sceneSession, reason);
4983     return WSError::WS_OK;
4984 }
4985 
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)4986 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
4987 {
4988     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
4989     if (persistentId == INVALID_SESSION_ID) {
4990         WLOGFE("id is invalid");
4991         return WSError::WS_ERROR_INVALID_SESSION;
4992     }
4993     auto focusedSession = GetSceneSession(focusedSessionId_);
4994     if (persistentId != focusedSessionId_ &&
4995         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
4996         TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
4997         return WSError::WS_DO_NOTHING;
4998     }
4999     // if pop menu created by desktop request unfocus, back to desktop
5000     auto lastSession = GetSceneSession(lastFocusedSessionId_);
5001     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
5002         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
5003         RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
5004             TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
5005             return WSError::WS_OK;
5006     }
5007     auto nextSession = GetNextFocusableSession(persistentId);
5008     if (nextSession == nullptr) {
5009         DumpAllSessionFocusableInfo(persistentId);
5010     }
5011 
5012     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5013     needBlockNotifyFocusStatusUntilForeground_ = false;
5014 
5015     if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
5016         return WSError::WS_OK;
5017     }
5018 
5019     return ShiftFocus(nextSession, reason);
5020 }
5021 
RequestAllAppSessionUnfocusInner()5022 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
5023 {
5024     TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
5025     auto focusedSession = GetSceneSession(focusedSessionId_);
5026     if (!focusedSession) {
5027         TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
5028         return WSError::WS_DO_NOTHING;
5029     }
5030     if (!focusedSession->IsAppSession()) {
5031         WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
5032         return WSError::WS_DO_NOTHING;
5033     }
5034     auto nextSession = GetTopFocusableNonAppSession();
5035 
5036     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5037     needBlockNotifyFocusStatusUntilForeground_ = false;
5038     return ShiftFocus(nextSession, FocusChangeReason::WIND);
5039 }
5040 
RequestFocusBasicCheck(int32_t persistentId)5041 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
5042 {
5043     // basic focus rule
5044     if (persistentId == INVALID_SESSION_ID) {
5045         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
5046         return WSError::WS_ERROR_INVALID_SESSION;
5047     }
5048     if (persistentId == focusedSessionId_) {
5049         TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
5050         return WSError::WS_DO_NOTHING;
5051     }
5052     return WSError::WS_OK;
5053 }
5054 
5055 /**
5056  * @note @window.focus
5057  * When high zOrder System Session unfocus, check if the last focused app window can focus.
5058  */
CheckLastFocusedAppSessionFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & nextSession)5059 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
5060     sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
5061 {
5062     if (focusedSession == nullptr || nextSession == nullptr) {
5063         return false;
5064     }
5065 
5066     TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
5067         lastFocusedAppSessionId_, nextSession->GetPersistentId());
5068 
5069     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
5070         return false;
5071     }
5072 
5073     if (!focusedSession->IsSystemSessionAboveApp()) {
5074         return false;
5075     }
5076 
5077     auto mode = nextSession->GetWindowMode();
5078     // only when next session is app, and in split or floation
5079     if (nextSession->IsAppSession() &&
5080         (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
5081          mode == WindowMode::WINDOW_MODE_FLOATING)) {
5082         if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
5083             WSError::WS_OK) {
5084             return true;
5085         }
5086         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5087     }
5088     return false;
5089 }
5090 
5091 /**
5092  * When switching focus, check if the blockingType window has been  traversed downwards.
5093  *
5094  * @return true: traversed downwards, false: not.
5095  */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession> & requestSceneSession,sptr<SceneSession> & focusedSession,bool includingAppSession)5096 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
5097     sptr<SceneSession>& focusedSession, bool includingAppSession)
5098 {
5099     uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
5100     uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
5101     TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
5102         requestSessionZOrder, focusedSessionZOrder);
5103     if  (requestSessionZOrder < focusedSessionZOrder)  {
5104         auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
5105             includingAppSession);
5106         uint32_t topNearestBlockingZOrder = 0;
5107         if  (topNearestBlockingFocusSession)  {
5108             topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
5109             TLOGD(WmsLogTag::WMS_FOCUS,  "requestSessionZOrder: %{public}d, focusedSessionZOrder:  %{public}d\
5110                 topNearestBlockingZOrder:  %{public}d",  requestSessionZOrder,  focusedSessionZOrder,
5111                 topNearestBlockingZOrder);
5112         }
5113         if  (focusedSessionZOrder >=  topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder)  {
5114             TLOGD(WmsLogTag::WMS_FOCUS,  "focus pass through, needs to be intercepted");
5115             return true;
5116         }
5117     }
5118     TLOGD(WmsLogTag::WMS_FOCUS, "not through");
5119     return false;
5120 }
5121 
CheckTopmostWindowFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & sceneSession)5122 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
5123 {
5124     bool isFocusedMainSessionTopmost =
5125         focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
5126     auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
5127     bool isFocusedSessionParentTopmost = parentSession &&
5128         parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
5129     if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
5130         (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
5131         return true;
5132     }
5133     return false;
5134 }
5135 
CheckRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5136 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5137 {
5138     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
5139          (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
5140         (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
5141          ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
5142         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
5143         return true;
5144     }
5145     return false;
5146 }
5147 
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)5148 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
5149     const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
5150 {
5151     if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
5152         focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
5153         return false;
5154     }
5155     if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
5156         return false;
5157     }
5158     return sceneSession->GetZOrder() < focusedSession->GetZOrder();
5159 }
5160 
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)5161 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
5162     FocusChangeReason reason)
5163 {
5164     TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
5165     int32_t persistentId = sceneSession->GetPersistentId();
5166     if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5167         TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5168         return WSError::WS_ERROR_INVALID_OPERATION;
5169     }
5170     // dialog get focus
5171     if (CheckRequestFocusImmdediately(sceneSession)) {
5172         return WSError::WS_DO_NOTHING;
5173     }
5174     // blocking-type session will block lower zOrder request focus
5175     auto focusedSession = GetSceneSession(focusedSessionId_);
5176     if (focusedSession) {
5177         TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d",  reason,
5178             byForeground);
5179         if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
5180             // return ok if focused session is topmost
5181             return WSError::WS_OK;
5182         }
5183         if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
5184             sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
5185             TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
5186             byForeground = false;
5187         }
5188         if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession,  focusedSession,  true))  {
5189             TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
5190             return WSError::WS_DO_NOTHING;
5191         }
5192         if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
5193             !byForeground)  {
5194             if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
5195                 && focusedSession->IsAppSession()) {
5196                 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
5197                 return WSError::WS_OK;
5198             }
5199         }
5200         bool isBlockingType = focusedSession->IsAppSession() ||
5201             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
5202         // temp check
5203         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
5204             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
5205                 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
5206                     persistentId);
5207                 return WSError::WS_DO_NOTHING;
5208         }
5209         // desktop click temp check
5210         if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
5211             TLOGW(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
5212             return WSError::WS_DO_NOTHING;
5213         }
5214     }
5215     return WSError::WS_OK;
5216 }
5217 
CheckParentSessionVisible(const sptr<SceneSession> & session)5218 bool SceneSessionManager::CheckParentSessionVisible(const sptr<SceneSession>& session)
5219 {
5220     if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
5221         session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
5222         GetSceneSession(session->GetParentPersistentId()) &&
5223         !IsSessionVisibleForeground(GetSceneSession(session->GetParentPersistentId()))) {
5224         return false;
5225     }
5226     return true;
5227 }
5228 
DumpAllSessionFocusableInfo(int32_t persistentId)5229 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
5230 {
5231     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
5232     auto func = [this](sptr<SceneSession> session) {
5233         if (session == nullptr) {
5234             return false;
5235         }
5236         bool parentVisible = CheckParentSessionVisible(session);
5237         bool sessionVisible = IsSessionVisible(session);
5238         TLOGI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
5239             "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
5240             session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
5241             session->GetFocusable(), sessionVisible, parentVisible);
5242         return false;
5243     };
5244     TraverseSessionTree(func, true);
5245 }
5246 
GetNextFocusableSession(int32_t persistentId)5247 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
5248 {
5249     TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
5250     bool previousFocusedSessionFound = false;
5251     sptr<SceneSession> ret = nullptr;
5252     auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
5253         if (session == nullptr) {
5254             return false;
5255         }
5256         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5257             TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5258             return false;
5259         }
5260         if (previousFocusedSessionFound && session->GetFocusable() &&
5261             IsSessionVisibleForeground(session) && CheckParentSessionVisible(session)) {
5262             ret = session;
5263             return true;
5264         }
5265         if (session->GetPersistentId() == persistentId) {
5266             previousFocusedSessionFound = true;
5267         }
5268         return false;
5269     };
5270     TraverseSessionTree(func, true);
5271     return ret;
5272 }
5273 
5274 /**
5275  * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
5276  * and it is the closest;
5277  */
GetTopNearestBlockingFocusSession(uint32_t zOrder,bool includingAppSession)5278 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
5279 {
5280     sptr<SceneSession> ret = nullptr;
5281     auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
5282         if (session == nullptr) {
5283             return false;
5284         }
5285         uint32_t sessionZOrder = session->GetZOrder();
5286         if (sessionZOrder <= zOrder) { // must be above the target session
5287             return false;
5288         }
5289         if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5290             TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
5291             return false;
5292         }
5293         auto parentSession = GetSceneSession(session->GetParentPersistentId());
5294         if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
5295             parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5296             parentSession->IsTopmost()) {
5297             TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
5298             return false;
5299         }
5300         bool isPhoneOrPad = systemConfig_.uiType_ == UI_TYPE_PHONE || systemConfig_.uiType_ == UI_TYPE_PAD;
5301         bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
5302                               (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
5303                               (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
5304         if (IsSessionVisibleForeground(session) && isBlockingType)  {
5305             ret = session;
5306             return true;
5307         }
5308         return false;
5309     };
5310     TraverseSessionTree(func, false);
5311     return ret;
5312 }
5313 
GetTopFocusableNonAppSession()5314 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
5315 {
5316     TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
5317     sptr<SceneSession> ret = nullptr;
5318     auto func = [this, &ret](sptr<SceneSession> session) {
5319         if (session == nullptr) {
5320             return false;
5321         }
5322         if (session->IsAppSession()) {
5323             return true;
5324         }
5325         if (session->GetFocusable() && IsSessionVisibleForeground(session)) {
5326             ret = session;
5327         }
5328         return false;
5329     };
5330     TraverseSessionTree(func, false);
5331     return ret;
5332 }
5333 
SetShiftFocusListener(const ProcessShiftFocusFunc & func)5334 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
5335 {
5336     TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
5337     shiftFocusFunc_ = func;
5338 }
5339 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5340 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5341 {
5342     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
5343     notifySCBAfterFocusedFunc_ = func;
5344 }
5345 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5346 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5347 {
5348     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
5349     notifySCBAfterUnfocusedFunc_ = func;
5350 }
5351 
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)5352 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
5353 {
5354     WLOGFD("SetCallingSessionIdSessionListenser");
5355     callingSessionIdChangeFunc_ = func;
5356 }
5357 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)5358 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
5359 {
5360     WLOGFD("SetStartUIAbilityErrorListener");
5361     startUIAbilityErrorFunc_ = func;
5362 }
5363 
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)5364 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
5365     const AbilityManagerCollaboratorRegisteredFunc& func)
5366 {
5367     auto task = [this, func] {
5368         abilityManagerCollaboratorRegisteredFunc_ = func;
5369     };
5370     taskScheduler_->PostAsyncTask(task, __func__);
5371 }
5372 
ShiftFocus(sptr<SceneSession> & nextSession,FocusChangeReason reason)5373 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)
5374 {
5375     // unfocus
5376     int32_t focusedId = focusedSessionId_;
5377     auto focusedSession = GetSceneSession(focusedSessionId_);
5378     UpdateFocusStatus(focusedSession, false);
5379     // focus
5380     int32_t nextId = INVALID_SESSION_ID;
5381     if (nextSession == nullptr) {
5382         std::string sessionLog(GetAllSessionFocusInfo());
5383         TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
5384             focusedSessionId_, sessionLog.c_str());
5385     } else {
5386         nextId = nextSession->GetPersistentId();
5387     }
5388     UpdateFocusStatus(nextSession, true);
5389     if (shiftFocusFunc_ != nullptr) {
5390         shiftFocusFunc_(nextId);
5391     }
5392     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5393     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5394     if (!scbPrevFocus && scbCurrFocus) {
5395         if (notifySCBAfterFocusedFunc_ != nullptr) {
5396             notifySCBAfterFocusedFunc_();
5397         }
5398     } else if (scbPrevFocus && !scbCurrFocus) {
5399         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5400             notifySCBAfterUnfocusedFunc_();
5401         }
5402     }
5403     TLOGI(WmsLogTag::WMS_FOCUS, "ShiftFocus, focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5404         focusedId, nextId, reason);
5405     return WSError::WS_OK;
5406 }
5407 
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5408 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5409 {
5410     if (sceneSession == nullptr) {
5411         if (isFocused) {
5412             SetFocusedSessionId(INVALID_SESSION_ID);
5413             lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5414         }
5415         return;
5416     }
5417     TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5418         sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5419     // set focused
5420     if (isFocused) {
5421         SetFocusedSessionId(sceneSession->GetPersistentId());
5422         if (sceneSession->IsAppOrLowerSystemSession()) {
5423             lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5424         }
5425     }
5426     sceneSession->UpdateFocus(isFocused);
5427     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5428         NotifyFocusStatus(sceneSession, isFocused);
5429     }
5430 }
5431 
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5432 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5433 {
5434     if (sceneSession == nullptr) {
5435         WLOGFE("[WMSComm]session is nullptr");
5436         if (isFocused) {
5437             auto prevSession = GetSceneSession(lastFocusedSessionId_);
5438             NotifyUnFocusedByMission(prevSession);
5439         }
5440         return;
5441     }
5442     int32_t persistentId = sceneSession->GetPersistentId();
5443 
5444     TLOGI(WmsLogTag::WMS_FOCUS,
5445         "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5446         sceneSession->GetSessionInfo().bundleName_.c_str(),
5447         sceneSession->GetSessionInfo().abilityName_.c_str(),
5448         sceneSession->GetWindowNameAllType().c_str(),
5449         persistentId, isFocused);
5450     if (isFocused) {
5451         if (IsSessionVisibleForeground(sceneSession)) {
5452             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5453         }
5454         UpdateBrightness(focusedSessionId_);
5455         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5456     }
5457     // notify window manager
5458     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5459         sceneSession->GetWindowId(),
5460         static_cast<DisplayId>(0),
5461         sceneSession->GetCallingPid(),
5462         sceneSession->GetCallingUid(),
5463         sceneSession->GetWindowType(),
5464         sceneSession->GetAbilityToken()
5465     );
5466     SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5467     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5468     sceneSession->NotifyFocusStatus(isFocused);
5469     // notify listenerController
5470     auto prevSession = GetSceneSession(lastFocusedSessionId_);
5471     if (isFocused && MissionChanged(prevSession, sceneSession)) {
5472         NotifyFocusStatusByMission(prevSession, sceneSession);
5473     }
5474 }
5475 
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)5476 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5477     const std::string& reason)
5478 {
5479     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5480     nlohmann::json payload;
5481     payload.emplace("uid", uid);
5482     payload.emplace("bundleName", bundleName);
5483     payload.emplace("reason", reason);
5484     nlohmann::json reply;
5485     int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5486     return ret;
5487 }
5488 
NotifyFocusStatusByMission(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5489 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5490 {
5491     if (listenerController_ != nullptr) {
5492         if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5493             TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", prevSession->GetMissionId());
5494             listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5495         }
5496         if (currSession && !currSession->GetSessionInfo().isSystem_) {
5497             TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionFocused, id: %{public}d", currSession->GetMissionId());
5498             listenerController_->NotifySessionFocused(currSession->GetMissionId());
5499         }
5500     }
5501 }
5502 
NotifyUnFocusedByMission(sptr<SceneSession> & sceneSession)5503 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5504 {
5505     if (listenerController_ == nullptr) {
5506         return;
5507     }
5508     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5509         TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", sceneSession->GetMissionId());
5510         listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5511     }
5512 }
5513 
MissionChanged(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5514 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5515 {
5516     if (prevSession == nullptr && currSession == nullptr) {
5517         return false;
5518     }
5519     if (prevSession == nullptr || currSession == nullptr) {
5520         return true;
5521     }
5522     return prevSession->GetMissionId() != currSession->GetMissionId();
5523 }
5524 
GetAllSessionFocusInfo()5525 std::string SceneSessionManager::GetAllSessionFocusInfo()
5526 {
5527     std::ostringstream os;
5528     auto func = [&os](sptr<SceneSession> session) {
5529         if (session == nullptr) {
5530             WLOGE("sceneSession is nullptr");
5531             return false;
5532         }
5533         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5534            " ,focusable: "<< session->GetFocusable() << ";";
5535         return false;
5536     };
5537     TraverseSessionTree(func, true);
5538     return os.str();
5539 }
5540 
UpdateFocus(int32_t persistentId,bool isFocused)5541 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5542 {
5543     auto task = [this, persistentId, isFocused]() {
5544         // notify session and client
5545         auto sceneSession = GetSceneSession(persistentId);
5546         if (sceneSession == nullptr) {
5547             WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5548             return WSError::WS_ERROR_INVALID_WINDOW;
5549         }
5550         WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5551             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5552         // focusId change
5553         if (isFocused) {
5554             SetFocusedSessionId(persistentId);
5555             UpdateBrightness(focusedSessionId_);
5556             FocusIDChange(persistentId, sceneSession);
5557         } else if (persistentId == GetFocusedSessionId()) {
5558             SetFocusedSessionId(INVALID_SESSION_ID);
5559         }
5560         // notify window manager
5561         sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5562             sceneSession->GetWindowId(),
5563             static_cast<DisplayId>(0),
5564             sceneSession->GetCallingPid(),
5565             sceneSession->GetCallingUid(),
5566             sceneSession->GetWindowType(),
5567             sceneSession->GetAbilityToken()
5568         );
5569         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5570         WSError res = WSError::WS_OK;
5571         res = sceneSession->UpdateFocus(isFocused);
5572         if (res != WSError::WS_OK) {
5573             return res;
5574         }
5575         WLOGFI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5576                sceneSession->GetSessionInfo().isSystem_);
5577         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
5578             if (isFocused) {
5579                 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
5580                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5581             } else {
5582                 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5583                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5584             }
5585         }
5586         return WSError::WS_OK;
5587     };
5588 
5589     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5590     return WSError::WS_OK;
5591 }
5592 
UpdateWindowMode(int32_t persistentId,int32_t windowMode)5593 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5594 {
5595     WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
5596     auto sceneSession = GetSceneSession(persistentId);
5597     if (sceneSession == nullptr) {
5598         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
5599         return WSError::WS_ERROR_INVALID_WINDOW;
5600     }
5601     WindowMode mode = static_cast<WindowMode>(windowMode);
5602     return sceneSession->UpdateWindowMode(mode);
5603 }
5604 
5605 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)5606 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
5607     MMI::PointerEvent::PointerItem& pointerItem)
5608 {
5609     struct PointerEventData {
5610         double x;
5611         double y;
5612         uint64_t time;
5613     } pointerEventData = {
5614         .x = pointerItem.GetDisplayX(),
5615         .y = pointerItem.GetDisplayY(),
5616         .time = pointerEvent->GetActionTime()
5617     };
5618 
5619     const uint32_t MAX_HMAC_SIZE = 64;
5620     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
5621     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
5622     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
5623     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
5624         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
5625         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
5626     }
5627 }
5628 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
5629 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)5630 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
5631 {
5632     if (!pointerEvent) {
5633         WLOGFE("pointerEvent is null");
5634         return WSError::WS_ERROR_NULLPTR;
5635     }
5636     MMI::PointerEvent::PointerItem pointerItem;
5637     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
5638         WLOGFE("Failed to get pointerItem");
5639         return WSError::WS_ERROR_INVALID_PARAM;
5640     }
5641 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
5642     FillSecCompEnhanceData(pointerEvent, pointerItem);
5643 #endif
5644     TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d,action=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
5645         pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
5646     pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
5647     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
5648     return WSError::WS_OK;
5649 }
5650 
SetScreenLocked(const bool isScreenLocked)5651 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
5652 {
5653     isScreenLocked_ = isScreenLocked;
5654     DeleteStateDetectTask();
5655 }
5656 
SetUserAuthPassed(bool isUserAuthPassed)5657 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
5658 {
5659     taskScheduler_->PostTask([this, isUserAuthPassed] {
5660         isUserAuthPassed_ = isUserAuthPassed;
5661     }, __func__);
5662 }
5663 
DeleteStateDetectTask()5664 void SceneSessionManager::DeleteStateDetectTask()
5665 {
5666     if (!IsScreenLocked()) {
5667         return;
5668     }
5669     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5670     for (auto iter : sceneSessionMap_) {
5671         auto& session = iter.second;
5672         if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
5673             taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
5674             DetectTaskInfo detectTaskInfo;
5675             session->SetDetectTaskInfo(detectTaskInfo);
5676         }
5677     }
5678 }
5679 
IsScreenLocked() const5680 bool SceneSessionManager::IsScreenLocked() const
5681 {
5682     return isScreenLocked_;
5683 }
5684 
IsUserAuthPassed() const5685 bool SceneSessionManager::IsUserAuthPassed() const
5686 {
5687     return isUserAuthPassed_;
5688 }
5689 
RegisterWindowChanged(const WindowChangedFunc & func)5690 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
5691 {
5692     WindowChangedFunc_ = func;
5693 }
5694 
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)5695 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
5696     const std::unordered_set<std::string>& privacyBundles)
5697 {
5698     bool needNotify = false;
5699     static int reSendTimes = MAX_RESEND_TIMES;
5700     std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
5701     do {
5702         if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
5703             TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
5704             needNotify = !privacyBundles.empty();
5705             break;
5706         }
5707         const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
5708         if (lastPrivacyBundles.size() != privacyBundles.size()) {
5709             TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
5710                   lastPrivacyBundles.size(), privacyBundles.size());
5711             needNotify = true;
5712             break;
5713         }
5714         for (const auto& bundle : lastPrivacyBundles) {
5715             if (privacyBundles.find(bundle) == privacyBundles.end()) {
5716                 needNotify = true;
5717                 break;
5718             }
5719         }
5720     } while (false);
5721 
5722     TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
5723           displayId, needNotify);
5724     if (needNotify) {
5725         reSendTimes = MAX_RESEND_TIMES;
5726         privacyBundleMap_[displayId] = privacyBundles;
5727     } else if (reSendTimes > 0) {
5728         needNotify = true;
5729         reSendTimes--;
5730         privacyBundleMap_[displayId] = privacyBundles;
5731     }
5732     return needNotify;
5733 }
5734 
UpdatePrivateStateAndNotify(uint32_t persistentId)5735 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
5736 {
5737     auto sceneSession = GetSceneSession(persistentId);
5738     if (sceneSession == nullptr) {
5739         TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
5740         return;
5741     }
5742 
5743     auto sessionProperty = sceneSession->GetSessionProperty();
5744     if (sessionProperty == nullptr) {
5745         TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
5746         return;
5747     }
5748     auto displayId = sessionProperty->GetDisplayId();
5749     std::unordered_set<std::string> privacyBundleList;
5750     GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5751     if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
5752         return;
5753     }
5754 
5755     std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
5756     ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5757         !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
5758     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
5759     if (!bundleListForNotify.empty()) {
5760         TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
5761     }
5762     for (const auto& bundle : bundleListForNotify) {
5763         TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
5764               displayId, bundle.c_str());
5765     }
5766 }
5767 
UpdatePrivateStateAndNotifyForAllScreens()5768 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
5769 {
5770     auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
5771     for (auto& iter : screenProperties) {
5772         auto displayId = iter.first;
5773         std::unordered_set<std::string> privacyBundleList;
5774         GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5775 
5776         ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5777             !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
5778     }
5779 }
5780 
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)5781 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
5782     std::unordered_set<std::string>& privacyBundles)
5783 {
5784     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5785     for (const auto& item : sceneSessionMap_) {
5786         sptr<SceneSession> sceneSession = item.second;
5787         if (sceneSession == nullptr) {
5788             TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
5789             continue;
5790         }
5791         auto sessionProperty = sceneSession->GetSessionProperty();
5792         if (sessionProperty == nullptr) {
5793             TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
5794             continue;
5795         }
5796         auto currentDisplayId = sessionProperty->GetDisplayId();
5797         if (displayId != currentDisplayId) {
5798             continue;
5799         }
5800         bool isForeground =  sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5801             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
5802         if (isForeground && sceneSession->GetParentSession() != nullptr) {
5803             isForeground = isForeground &&
5804                 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
5805                 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
5806         }
5807         bool isPrivate = sessionProperty->GetPrivacyMode() ||
5808             sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
5809         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
5810         if ((isForeground || IsSystemWindowVisible) && isPrivate) {
5811             if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
5812                 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
5813             } else {
5814                 TLOGD(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
5815                 privacyBundles.insert(sceneSession->GetWindowName());
5816             }
5817         }
5818     }
5819 }
5820 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5821 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5822 {
5823     NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
5824         this->OnSessionStateChange(persistentId, state);
5825     };
5826     if (sceneSession == nullptr) {
5827         WLOGFE("session is nullptr");
5828         return;
5829     }
5830     sceneSession->SetSessionStateChangeNotifyManagerListener(func);
5831     WLOGFD("RegisterSessionStateChangeFunc success");
5832 }
5833 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5834 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5835 {
5836     wptr<SceneSessionManager> weakSessionManager = this;
5837     NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
5838         auto sceneSessionManager = weakSessionManager.promote();
5839         if (sceneSessionManager == nullptr) {
5840             return;
5841         }
5842         sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
5843     };
5844     if (sceneSession == nullptr) {
5845         WLOGFE("session is nullptr");
5846         return;
5847     }
5848     sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
5849 }
5850 
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)5851 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5852 {
5853     NotifyRequestFocusStatusNotifyManagerFunc func =
5854     [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
5855         this->RequestFocusStatus(persistentId, isFocused, byForeground, reason);
5856     };
5857     if (sceneSession == nullptr) {
5858         WLOGFE("session is nullptr");
5859         return;
5860     }
5861     sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
5862     WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
5863 }
5864 
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)5865 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
5866 {
5867     GetStateFromManagerFunc func = [this](const ManagerState key) {
5868         switch (key)
5869         {
5870         case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
5871             return this->IsScreenLocked();
5872             break;
5873         default:
5874             return false;
5875             break;
5876         }
5877     };
5878     if (sceneSession == nullptr) {
5879         WLOGFE("session is nullptr");
5880         return;
5881     }
5882     sceneSession->SetGetStateFromManagerListener(func);
5883     WLOGFD("RegisterGetStateFromManagerFunc success");
5884 }
5885 
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)5886 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5887 {
5888     SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
5889         const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
5890         if (sceneSession == nullptr || property == nullptr) {
5891             TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
5892             return;
5893         }
5894         switch (action) {
5895             case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
5896                 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
5897                 break;
5898             case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
5899             case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
5900             case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
5901             case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
5902             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
5903             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
5904                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5905                 break;
5906             case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
5907                 SetBrightness(sceneSession, property->GetBrightness());
5908                 break;
5909             case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
5910             case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
5911                 UpdatePrivateStateAndNotify(property->GetPersistentId());
5912                 break;
5913             case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
5914                 CheckAndNotifyWaterMarkChangedResult();
5915                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5916                 break;
5917             case WSPropertyChangeAction::ACTION_UPDATE_MODE:
5918                 if (sceneSession->GetSessionProperty() != nullptr) {
5919                     ProcessWindowModeType();
5920                 }
5921                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5922                 break;
5923             case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5924                 HandleHideNonSystemFloatingWindows(property, sceneSession);
5925                 break;
5926             case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
5927                 FlushWindowInfoToMMI();
5928                 break;
5929             default:
5930                 break;
5931         }
5932     };
5933     if (sceneSession != nullptr) {
5934         sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
5935     }
5936 }
5937 
OnSessionStateChange(int32_t persistentId,const SessionState & state)5938 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
5939     int32_t persistentId, const SessionState& state)
5940 {
5941     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
5942     WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
5943     auto sceneSession = GetSceneSession(persistentId);
5944     if (sceneSession == nullptr) {
5945         WLOGFD("session is nullptr");
5946         return;
5947     }
5948     switch (state) {
5949         case SessionState::STATE_FOREGROUND:
5950             ProcessFocusWhenForeground(sceneSession);
5951             if (!IsSessionVisibleForeground(sceneSession)) {
5952                 sceneSession->SetPostProcessProperty(true);
5953                 break;
5954             }
5955             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
5956             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
5957             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
5958             UpdatePrivateStateAndNotify(persistentId);
5959             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5960                 ProcessSubSessionForeground(sceneSession);
5961             }
5962             break;
5963         case SessionState::STATE_BACKGROUND:
5964             NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
5965             RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
5966             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
5967             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
5968             HandleKeepScreenOn(sceneSession, false);
5969             UpdatePrivateStateAndNotify(persistentId);
5970             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5971                 ProcessSubSessionBackground(sceneSession);
5972             }
5973             break;
5974         default:
5975             break;
5976     }
5977     ProcessWindowModeType();
5978 }
5979 
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)5980 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
5981 {
5982     auto persistentId = sceneSession->GetPersistentId();
5983     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5984         persistentId == focusedSessionId_) {
5985         if (needBlockNotifyFocusStatusUntilForeground_) {
5986             needBlockNotifyUnfocusStatus_ = false;
5987             needBlockNotifyFocusStatusUntilForeground_ = false;
5988             NotifyFocusStatus(sceneSession, true);
5989         }
5990     } else if (!sceneSession->IsFocusedOnShow()) {
5991         sceneSession->SetFocusedOnShow(true);
5992     } else {
5993         if (Session::IsScbCoreEnabled()) {
5994             ProcessFocusWhenForegroundScbCore(sceneSession);
5995         } else {
5996             RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5997         }
5998         RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5999     }
6000 }
6001 
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)6002 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
6003 {
6004     if (sceneSession == nullptr) {
6005         TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
6006         return;
6007     }
6008     if (sceneSession->IsFocusableOnShow()) {
6009         if (IsSessionVisibleForeground(sceneSession)) {
6010             RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
6011         } else {
6012             PostProcessFocusState state = {true, true, FocusChangeReason::APP_FOREGROUND};
6013             sceneSession->SetPostProcessFocusState(state);
6014         }
6015     } else {
6016         TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
6017             sceneSession->GetPersistentId());
6018     }
6019 }
6020 
ProcessWindowModeType()6021 void SceneSessionManager::ProcessWindowModeType()
6022 {
6023     if (isScreenLocked_) {
6024         return;
6025     }
6026     NotifyRSSWindowModeTypeUpdate();
6027 }
6028 
IsSmallFoldProduct()6029 static bool IsSmallFoldProduct()
6030 {
6031     static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
6032     if (foldScreenType.empty()) {
6033         TLOGE(WmsLogTag::DEFAULT, "foldScreenType is empty");
6034         return false;
6035     }
6036     return foldScreenType[0] == '2';
6037 }
6038 
IsInSecondaryScreen(const sptr<SceneSession> & sceneSession)6039 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
6040 {
6041     auto sessionProperty = sceneSession->GetSessionProperty();
6042     if (sessionProperty == nullptr) {
6043         TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
6044         return false;
6045     }
6046     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6047     return sessionProperty->GetDisplayId() != defaultScreenId;
6048 }
6049 
CheckWindowModeType()6050 WindowModeType SceneSessionManager::CheckWindowModeType()
6051 {
6052     bool inSplit = false;
6053     bool inFloating = false;
6054     bool fullScreen = false;
6055     bool isSmallFold = IsSmallFoldProduct();
6056     {
6057         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6058         for (const auto& session : sceneSessionMap_) {
6059             if (session.second == nullptr ||
6060                 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
6061                 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
6062                 continue;
6063             }
6064             if (isSmallFold && IsInSecondaryScreen(session.second)) {
6065                 continue;
6066             }
6067             auto mode = session.second->GetWindowMode();
6068             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
6069                 inSplit = true;
6070             }
6071             if (mode == WindowMode::WINDOW_MODE_FLOATING) {
6072                 inFloating = true;
6073             }
6074             if (WindowHelper::IsFullScreenWindow(mode)) {
6075                 fullScreen = true;
6076             }
6077         }
6078     }
6079 
6080     WindowModeType type;
6081     if (inSplit) {
6082         if (inFloating) {
6083             type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
6084         } else {
6085             type = WindowModeType::WINDOW_MODE_SPLIT;
6086         }
6087     } else {
6088         if (inFloating) {
6089             if (fullScreen) {
6090                 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
6091             } else {
6092                 type = WindowModeType::WINDOW_MODE_FLOATING;
6093             }
6094         } else if (fullScreen) {
6095             type = WindowModeType::WINDOW_MODE_FULLSCREEN;
6096         } else {
6097             type = WindowModeType::WINDOW_MODE_OTHER;
6098         }
6099     }
6100     return type;
6101 }
6102 
NotifyRSSWindowModeTypeUpdate()6103 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
6104 {
6105     WindowModeType type = CheckWindowModeType();
6106     if (lastWindowModeType_ == type) {
6107         return;
6108     }
6109     lastWindowModeType_ = type;
6110     TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
6111         static_cast<uint8_t>(type));
6112     SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
6113 }
6114 
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)6115 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
6116 {
6117     if (sceneSession == nullptr) {
6118         WLOGFD("session is nullptr");
6119         return;
6120     }
6121     std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
6122     for (const auto& subSession : sceneSession->GetSubSession()) {
6123         if (subSession == nullptr) {
6124             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
6125             continue;
6126         }
6127         if (subSession->IsTopmost()) {
6128             modalVec.push_back(subSession);
6129             TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
6130             continue;
6131         }
6132         const auto& state = subSession->GetSessionState();
6133         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6134             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
6135             continue;
6136         }
6137         RequestSessionFocus(subSession->GetPersistentId(), true);
6138         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6139         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
6140     }
6141 
6142     for (const auto& modal : modalVec) {
6143         if (modal == nullptr) {
6144             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
6145             continue;
6146         }
6147         const auto& state = modal->GetSessionState();
6148         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6149             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
6150             continue;
6151         }
6152         auto modalSession = GetSceneSession(modal->GetPersistentId());
6153         if (modalSession == nullptr) {
6154             TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
6155             continue;
6156         }
6157         NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6158         if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
6159             needBlockNotifyUnfocusStatus_ = false;
6160             needBlockNotifyFocusStatusUntilForeground_ = false;
6161             NotifyFocusStatus(modalSession, true);
6162         }
6163         HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
6164     }
6165 }
6166 
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6167 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6168 {
6169     // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
6170     sptr<SceneSession> mainSession = nullptr;
6171     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6172         mainSession = sceneSession;
6173     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6174         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6175     }
6176     if (mainSession == nullptr) {
6177         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6178         return WSError::WS_DO_NOTHING;
6179     }
6180 
6181     std::vector<sptr<SceneSession>> topmostVec;
6182     for (auto subSession : mainSession->GetSubSession()) {
6183         if (subSession && subSession->IsTopmost()) {
6184             topmostVec.push_back(subSession);
6185         }
6186     }
6187     if (std::find_if(topmostVec.begin(), topmostVec.end(),
6188         [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6189         != topmostVec.end()) {
6190             TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
6191             return WSError::WS_OK;
6192     }
6193     WSError ret = WSError::WS_DO_NOTHING;
6194     for (auto topmostSession : topmostVec) {
6195         if (topmostSession == nullptr) {
6196             continue;
6197         }
6198         // no need to consider order, since rule of zOrder
6199         if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
6200             ret = WSError::WS_OK;
6201         }
6202     }
6203     return ret;
6204 }
6205 
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6206 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6207 {
6208     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
6209     sptr<SceneSession> mainSession = nullptr;
6210     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6211         mainSession = sceneSession;
6212     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6213         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6214     }
6215     if (mainSession == nullptr) {
6216         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6217         return WSError::WS_DO_NOTHING;
6218     }
6219     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
6220     if (std::find_if(dialogVec.begin(), dialogVec.end(),
6221         [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6222         != dialogVec.end()) {
6223             TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
6224             return WSError::WS_OK;
6225     }
6226     WSError ret = WSError::WS_DO_NOTHING;
6227     for (auto dialog : dialogVec) {
6228         if (dialog == nullptr) {
6229             continue;
6230         }
6231         // no need to consider order, since rule of zOrder
6232         if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
6233             ret = WSError::WS_OK;
6234         }
6235     }
6236     return ret;
6237 }
6238 
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)6239 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
6240 {
6241     if (sceneSession == nullptr) {
6242         WLOGFD("session is nullptr");
6243         return;
6244     }
6245     for (const auto& subSession : sceneSession->GetSubSession()) {
6246         if (subSession == nullptr) {
6247             WLOGFD("sub session is nullptr");
6248             continue;
6249         }
6250         const auto& state = subSession->GetSessionState();
6251         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6252             WLOGFD("sub session is not active");
6253             continue;
6254         }
6255         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6256         HandleKeepScreenOn(subSession, false);
6257         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
6258     }
6259     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
6260     for (const auto& dialog : dialogVec) {
6261         if (dialog == nullptr) {
6262             TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
6263             continue;
6264         }
6265         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
6266         if (dialogSession == nullptr) {
6267             TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
6268             continue;
6269         }
6270         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6271         HandleKeepScreenOn(dialogSession, false);
6272         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
6273     }
6274     for (const auto& toastSession : sceneSession->GetToastSession()) {
6275         if (toastSession == nullptr) {
6276             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
6277             continue;
6278         }
6279         const auto& state = toastSession->GetSessionState();
6280         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6281             continue;
6282         }
6283         NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6284         HandleKeepScreenOn(toastSession, false);
6285         UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
6286         toastSession->SetActive(false);
6287         toastSession->BackgroundTask();
6288     }
6289 }
6290 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)6291 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
6292     const sptr<WindowSessionProperty>& property)
6293 {
6294     if (sceneSession == nullptr) {
6295         WLOGFD("session is nullptr");
6296         return WSError::WS_ERROR_NULLPTR;
6297     }
6298     auto sessionProperty = sceneSession->GetSessionProperty();
6299     if (sessionProperty == nullptr) {
6300         return WSError::WS_ERROR_NULLPTR;
6301     }
6302     uint32_t flags = property->GetWindowFlags();
6303     uint32_t oldFlags = sessionProperty->GetWindowFlags();
6304     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6305         (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6306         !property->GetSystemCalling()) {
6307             WLOGFE("Set window flags permission denied");
6308             return WSError::WS_ERROR_NOT_SYSTEM_APP;
6309     }
6310     sessionProperty->SetWindowFlags(flags);
6311     CheckAndNotifyWaterMarkChangedResult();
6312     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6313         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6314     }
6315     WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
6316     return WSError::WS_OK;
6317 }
6318 
CheckAndNotifyWaterMarkChangedResult()6319 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
6320 {
6321     bool currentWaterMarkShowState = false;
6322     {
6323         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6324         for (const auto& iter: sceneSessionMap_) {
6325             auto& session = iter.second;
6326             if (!session) {
6327                 continue;
6328             }
6329             auto sessionProperty = session->GetSessionProperty();
6330             if (!sessionProperty) {
6331                 continue;
6332             }
6333             bool hasWaterMark = sessionProperty->GetWindowFlags() &
6334                 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
6335             bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
6336             if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
6337                 currentWaterMarkShowState = true;
6338                 break;
6339             }
6340         }
6341         if (combinedExtWindowFlags_.waterMarkFlag) {
6342             TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
6343             currentWaterMarkShowState = true;
6344         }
6345     }
6346     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
6347         lastWaterMarkShowState_ = currentWaterMarkShowState;
6348         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
6349     }
6350 }
6351 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)6352 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
6353 {
6354     WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
6355     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
6356     return WSError::WS_OK;
6357 }
6358 
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const6359 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
6360 {
6361     if (!bundleMgr_) {
6362         WLOGFE("bundle manager is nullptr.");
6363         return;
6364     }
6365 
6366     AAFwk::Want want;
6367     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
6368     auto uid = abilityInfo.uid;
6369     want.SetParam("uid", uid);
6370     bundleMgr_->ProcessPreload(want);
6371 }
6372 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)6373 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
6374 {
6375     auto scnSession = GetSceneSession(persistentId);
6376     if (scnSession == nullptr) {
6377         TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
6378         return;
6379     }
6380 
6381     const auto& sessionInfo = scnSession->GetSessionInfo();
6382     if (IsAtomicServiceFreeInstall(sessionInfo)) {
6383         TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
6384             scnSession->GetPersistentId(), scnSession->GetWindowType());
6385         FillSessionInfo(scnSession);
6386     }
6387 
6388     TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
6389         scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
6390         sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6391     auto abilityInfoPtr = sessionInfo.abilityInfo;
6392     if (abilityInfoPtr == nullptr) {
6393         TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
6394         return;
6395     }
6396     if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
6397         !(abilityInfoPtr->excludeFromMissions)) {
6398         WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
6399         listenerController_->NotifySessionCreated(persistentId);
6400     }
6401 
6402     if (eventHandler_ != nullptr) {
6403         auto task = [persistentId]() {
6404             AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6405         };
6406         WLOGFI("Post CompleteFirstFrameDrawing task.");
6407         bool ret = eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6408         if (!ret) {
6409             WLOGFE("Report post first frame task failed. the task name is CompleteFirstFrameDrawing");
6410         }
6411     }
6412 
6413     if (taskScheduler_ == nullptr) {
6414         return;
6415     }
6416     auto task = [this, abilityInfoPtr]() {
6417         ProcessPreload(*abilityInfoPtr);
6418     };
6419     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6420 }
6421 
NotifySessionMovedToFront(int32_t persistentId)6422 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6423 {
6424     WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
6425     auto scnSession = GetSceneSession(persistentId);
6426     if (scnSession == nullptr) {
6427         WLOGFE("session is invalid with %{public}d", persistentId);
6428         return;
6429     }
6430     WLOGFI("NotifySessionMovedToFront, id: %{public}d, system: %{public}d", scnSession->GetPersistentId(),
6431            scnSession->GetSessionInfo().isSystem_);
6432     if (listenerController_ != nullptr &&
6433         !scnSession->GetSessionInfo().isSystem_ &&
6434         (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
6435         !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6436         listenerController_->NotifySessionMovedToFront(persistentId);
6437     }
6438 }
6439 
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)6440 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6441 {
6442     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
6443     auto task = [this, &token, &label]() {
6444         auto sceneSession = FindSessionByToken(token);
6445         if (sceneSession == nullptr) {
6446             WLOGFI("fail to find session by token");
6447             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6448         }
6449         sceneSession->SetSessionLabel(label);
6450         WLOGFI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6451             sceneSession->GetSessionInfo().isSystem_);
6452         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
6453             WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6454             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6455         }
6456         return WSError::WS_OK;
6457     };
6458     return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6459 }
6460 
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)6461 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6462     const std::shared_ptr<Media::PixelMap>& icon)
6463 {
6464     WLOGFI("Enter");
6465     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6466         WLOGFE("The caller is not system-app, can not use system-api");
6467         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6468     }
6469 
6470     auto task = [this, &token, &icon]() {
6471         auto sceneSession = FindSessionByToken(token);
6472         if (sceneSession == nullptr) {
6473             WLOGFI("fail to find session by token");
6474             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6475         }
6476         sceneSession->SetSessionIcon(icon);
6477         WLOGFI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6478             sceneSession->GetSessionInfo().isSystem_);
6479         if (listenerController_ != nullptr &&
6480             !sceneSession->GetSessionInfo().isSystem_ &&
6481             (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
6482             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6483             WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6484             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6485         }
6486         return WSError::WS_OK;
6487     };
6488     return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6489 }
6490 
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)6491 WSError SceneSessionManager::IsValidSessionIds(
6492     const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6493 {
6494     WLOGFI("Enter");
6495     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6496     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6497         auto search = sceneSessionMap_.find(sessionIds.at(i));
6498         if (search == sceneSessionMap_.end() || search->second == nullptr) {
6499             results.push_back(false);
6500             continue;
6501         }
6502         results.push_back(true);
6503     }
6504     return WSError::WS_OK;
6505 }
6506 
RegisterSessionListener(const sptr<ISessionListener> & listener)6507 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6508 {
6509     WLOGFI("Enter");
6510     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6511         WLOGFE("The caller is not system-app, can not use system-api");
6512         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6513     }
6514     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6515         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6516         return WSError::WS_ERROR_INVALID_PERMISSION;
6517     }
6518     auto task = [this, &listener]() {
6519         WSError ret = WSError::WS_DO_NOTHING;
6520         if (listenerController_ != nullptr) {
6521             ret = listenerController_->AddSessionListener(listener);
6522         } else {
6523             WLOGFE("The listenerController is nullptr");
6524         }
6525 
6526         // app continue report for distributed scheduled service
6527         SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6528             static_cast<int32_t>(ret));
6529 
6530         return ret;
6531     };
6532     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6533 }
6534 
UnRegisterSessionListener(const sptr<ISessionListener> & listener)6535 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6536 {
6537     WLOGFI("Enter");
6538     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6539         WLOGFE("The caller is not system-app, can not use system-api");
6540         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6541     }
6542     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6543         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6544         return WSError::WS_ERROR_INVALID_PERMISSION;
6545     }
6546     auto task = [this, &listener]() {
6547         if (listenerController_ != nullptr) {
6548             listenerController_->DelSessionListener(listener);
6549             return WSError::WS_OK;
6550         } else {
6551             WLOGFE("The listenerController is nullptr");
6552             return WSError::WS_DO_NOTHING;
6553         }
6554     };
6555     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6556 }
6557 
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6558 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6559                                              std::vector<SessionInfoBean>& sessionInfos)
6560 {
6561     WLOGFI("Enter num max %{public}d", numMax);
6562     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6563         WLOGFE("The caller is not system-app, can not use system-api");
6564         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6565     }
6566     if (!SessionPermission::VerifySessionPermission()) {
6567         WLOGFE("The caller has not permission granted");
6568         return WSError::WS_ERROR_INVALID_PERMISSION;
6569     }
6570     auto task = [this, &deviceId, numMax, &sessionInfos]() {
6571         if (CheckIsRemote(deviceId)) {
6572             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6573             if (ret != ERR_OK) {
6574                 return WSError::WS_ERROR_INVALID_PARAM;
6575             } else {
6576                 return WSError::WS_OK;
6577             }
6578         }
6579         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6580         std::vector<sptr<SceneSession>> sceneSessionInfos;
6581         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6582         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6583             auto sceneSession = iter->second;
6584             if (sceneSession == nullptr) {
6585                 WLOGFE("session is nullptr");
6586                 continue;
6587             }
6588             auto sessionInfo = sceneSession->GetSessionInfo();
6589             if (sessionInfo.isSystem_) {
6590                 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
6591                 continue;
6592             }
6593             auto want = sessionInfo.want;
6594             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
6595                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6596                     sceneSession->GetPersistentId());
6597                 continue;
6598             }
6599             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
6600                 break;
6601             }
6602             WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
6603                 sessionInfo.bundleName_.c_str());
6604             sceneSessionInfos.emplace_back(sceneSession);
6605         }
6606         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
6607     };
6608     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
6609 }
6610 
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)6611 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
6612 {
6613     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
6614     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
6615         TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
6616         return WSError::WS_ERROR_INVALID_PERMISSION;
6617     }
6618     if (pid < 0) {
6619         return WSError::WS_ERROR_INVALID_PARAM;
6620     }
6621     auto task = [this, pid, &windowStates] {
6622         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6623         for (const auto& [_, sceneSession] : sceneSessionMap_) {
6624             if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
6625                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6626                 MainWindowState windowState;
6627                 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
6628                 windowState.isVisible_ = sceneSession->GetRSVisible();
6629                 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
6630                 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
6631                 windowStates.emplace_back(windowState);
6632             }
6633         }
6634         return WSError::WS_OK;
6635     };
6636     return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
6637 }
6638 
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6639 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
6640                                                std::vector<SessionInfoBean>& sessionInfos)
6641 {
6642     TLOGI(WmsLogTag::DEFAULT, "begin");
6643     int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
6644     if (result != ERR_OK) {
6645         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6646         return result;
6647     }
6648     return ERR_OK;
6649 }
6650 
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6651 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
6652                                             int32_t persistentId, SessionInfoBean& sessionInfo)
6653 {
6654     WLOGFI("id %{public}d", persistentId);
6655     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6656         WLOGFE("The caller is not system-app, can not use system-api");
6657         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6658     }
6659     if (!SessionPermission::VerifySessionPermission()) {
6660         WLOGFE("The caller has not permission granted");
6661         return WSError::WS_ERROR_INVALID_PERMISSION;
6662     }
6663     auto task = [this, &deviceId, persistentId, &sessionInfo]() {
6664         if (CheckIsRemote(deviceId)) {
6665             int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
6666             if (ret != ERR_OK) {
6667                 return WSError::WS_ERROR_INVALID_PARAM;
6668             } else {
6669                 return WSError::WS_OK;
6670             }
6671         }
6672         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6673         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6674         iter = sceneSessionMap_.find(persistentId);
6675         if (iter != sceneSessionMap_.end()) {
6676             auto sceneSession = iter->second;
6677             if (sceneSession == nullptr) {
6678                 WLOGFE("session: %{public}d is nullptr", persistentId);
6679                 return WSError::WS_ERROR_INVALID_PARAM;
6680             }
6681             auto sceneSessionInfo = sceneSession->GetSessionInfo();
6682             if (sceneSessionInfo.isSystem_) {
6683                 WLOGFD("sessionId: %{public}d  isSystemScene", persistentId);
6684                 return WSError::WS_ERROR_INVALID_PARAM;
6685             }
6686             auto want = sceneSessionInfo.want;
6687             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
6688                 want->GetElement().GetBundleName().empty()) {
6689                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6690                     persistentId);
6691                 return WSError::WS_ERROR_INTERNAL_ERROR;
6692             }
6693             WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
6694                 sceneSessionInfo.bundleName_.c_str());
6695             return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
6696         } else {
6697             WLOGFW("sessionId: %{public}d not found", persistentId);
6698             return WSError::WS_ERROR_INVALID_PARAM;
6699         }
6700     };
6701     return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
6702 }
6703 
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)6704 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
6705     SessionInfoBean& sessionInfo)
6706 {
6707     TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
6708         continueSessionId.c_str());
6709     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6710         TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
6711         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6712     }
6713     if (!SessionPermission::VerifySessionPermission()) {
6714         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
6715         return WSError::WS_ERROR_INVALID_PERMISSION;
6716     }
6717     auto task = [this, continueSessionId, &sessionInfo]() {
6718         WSError ret = WSError::WS_ERROR_INVALID_SESSION;
6719         {
6720             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6721             for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
6722                 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
6723                     ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
6724                     break;
6725                 }
6726             }
6727         }
6728 
6729         TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
6730         // app continue report for distributed scheduled service
6731         SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
6732             static_cast<int32_t>(ret));
6733         return ret;
6734     };
6735     return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
6736 }
6737 
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6738 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
6739                                               int32_t persistentId, SessionInfoBean& sessionInfo)
6740 {
6741     WLOGFI("GetRemoteSessionInfoFromDms begin");
6742     std::vector<SessionInfoBean> sessionVector;
6743     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
6744     if (result != ERR_OK) {
6745         return result;
6746     }
6747     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
6748         if (iter->id == persistentId) {
6749             sessionInfo = *iter;
6750             return ERR_OK;
6751         }
6752     }
6753     WLOGFW("missionId not found");
6754     return ERR_INVALID_VALUE;
6755 }
6756 
CheckIsRemote(const std::string & deviceId)6757 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
6758 {
6759     if (deviceId.empty()) {
6760         WLOGFI("CheckIsRemote: deviceId is empty.");
6761         return false;
6762     }
6763     std::string localDeviceId;
6764     if (!GetLocalDeviceId(localDeviceId)) {
6765         WLOGFE("CheckIsRemote: get local deviceId failed");
6766         return false;
6767     }
6768     if (localDeviceId == deviceId) {
6769         WLOGFI("CheckIsRemote: deviceId is local.");
6770         return false;
6771     }
6772     WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
6773     return true;
6774 }
6775 
GetLocalDeviceId(std::string & localDeviceId)6776 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
6777 {
6778     auto localNode = std::make_unique<NodeBasicInfo>();
6779     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
6780     if (errCode != ERR_OK) {
6781         WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
6782         return false;
6783     }
6784     if (localNode != nullptr) {
6785         localDeviceId = localNode->networkId;
6786         WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
6787         return true;
6788     }
6789     WLOGFE("localDeviceId null");
6790     return false;
6791 }
6792 
AnonymizeDeviceId(const std::string & deviceId)6793 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
6794 {
6795     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
6796         return EMPTY_DEVICE_ID;
6797     }
6798     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
6799     anonDeviceId.append("******");
6800     return anonDeviceId;
6801 }
6802 
DumpSessionAll(std::vector<std::string> & infos)6803 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
6804 {
6805     WLOGFI("Dump all session.");
6806     if (!SessionPermission::IsSystemCalling()) {
6807         WLOGFE("DumpSessionAll permission denied!");
6808         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6809     }
6810 
6811     auto task = [this, &infos]() {
6812         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6813         infos.push_back(dumpInfo);
6814         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6815         for (const auto &item : sceneSessionMap_) {
6816             auto& session = item.second;
6817             if (session) {
6818                 session->DumpSessionInfo(infos);
6819             }
6820         }
6821         return WSError::WS_OK;
6822     };
6823 
6824     return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
6825 }
6826 
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)6827 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
6828 {
6829     WLOGFI("Dump session with id %{public}d", persistentId);
6830     if (!SessionPermission::IsSystemCalling()) {
6831         WLOGFE("DumpSessionWithId permission denied!");
6832         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6833     }
6834 
6835     auto task = [this, persistentId, &infos]() {
6836         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6837         infos.push_back(dumpInfo);
6838         auto session = GetSceneSession(persistentId);
6839         if (session) {
6840             session->DumpSessionInfo(infos);
6841         } else {
6842             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
6843         }
6844         return WSError::WS_OK;
6845     };
6846 
6847     return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
6848 }
6849 
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6850 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
6851     const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6852 {
6853     if (bundleMgr_ == nullptr) {
6854         WLOGFE("bundleMgr_ is nullptr");
6855         return WSError::WS_ERROR_NULLPTR;
6856     }
6857     auto elementName = want.GetElement();
6858     int32_t ret{0};
6859     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6860         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6861         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6862         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6863         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6864         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6865     std::vector<AppExecFwk::BundleInfo> bundleInfos;
6866     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
6867         WLOGFD("want is empty queryAllAbilityInfos");
6868         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
6869         if (ret) {
6870             WLOGFE("Query all ability infos from BMS failed!");
6871             return WSError::WS_ERROR_INVALID_PARAM;
6872         }
6873     } else if (!elementName.GetBundleName().empty()) {
6874         AppExecFwk::BundleInfo bundleInfo;
6875         WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
6876         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
6877         if (ret) {
6878             WLOGFE("Query ability info from BMS failed!");
6879             return WSError::WS_ERROR_INVALID_PARAM;
6880         }
6881         bundleInfos.push_back(bundleInfo);
6882     } else {
6883         WLOGFE("invalid want:%{public}s", want.ToString().c_str());
6884         return WSError::WS_ERROR_INVALID_PARAM;
6885     }
6886     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6887 }
6888 
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6889 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
6890     const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6891 {
6892     if (bundleMgr_ == nullptr) {
6893         TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
6894         return WSError::WS_ERROR_NULLPTR;
6895     }
6896     if (bundleNames.empty()) {
6897         TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
6898         return WSError::WS_ERROR_INVALID_PARAM;
6899     }
6900     auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6901                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6902                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6903                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6904                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6905                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
6906     std::vector<AppExecFwk::BundleInfo> bundleInfos;
6907     auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
6908     if (ret) {
6909         TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
6910         return WSError::WS_ERROR_INVALID_PARAM;
6911     }
6912     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6913 }
6914 
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)6915 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
6916     const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
6917 {
6918     if (bundleMgr_ == nullptr) {
6919         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
6920         return WSError::WS_ERROR_NULLPTR;
6921     }
6922     auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6923         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6924         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6925         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6926         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6927         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6928     AppExecFwk::BundleInfo bundleInfo;
6929     if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
6930         TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
6931         return WSError::WS_ERROR_INVALID_PARAM;
6932     }
6933     auto& hapModulesList = bundleInfo.hapModuleInfos;
6934     if (hapModulesList.empty()) {
6935         TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
6936         return WSError::WS_ERROR_INVALID_PARAM;
6937     }
6938     auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
6939     for (auto& hapModule : hapModulesList) {
6940         auto& abilityInfoList = hapModule.abilityInfos;
6941         for (auto& abilityInfo : abilityInfoList) {
6942             if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
6943                 scbAbilityInfo.abilityInfo_ = abilityInfo;
6944                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6945                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6946                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6947                 return WSError::WS_OK;
6948             }
6949         }
6950     }
6951     TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
6952     return WSError::WS_ERROR_INVALID_PARAM;
6953 }
6954 
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)6955 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
6956     std::vector<SCBAbilityInfo>& scbAbilityInfos)
6957 {
6958     if (bundleInfos.empty()) {
6959         WLOGFE("bundleInfos is empty");
6960         return WSError::WS_ERROR_INVALID_PARAM;
6961     }
6962     for (auto& bundleInfo : bundleInfos) {
6963         auto& hapModulesList = bundleInfo.hapModuleInfos;
6964         auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
6965         if (hapModulesList.empty()) {
6966             WLOGFD("hapModulesList is empty");
6967             continue;
6968         }
6969         if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
6970             bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
6971             auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
6972                 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
6973             if (iter != hapModulesList.end()) {
6974                 SCBAbilityInfo scbAbilityInfo;
6975                 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
6976                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6977                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6978                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6979                 scbAbilityInfos.push_back(scbAbilityInfo);
6980                 continue;
6981             }
6982         }
6983         for (auto& hapModule : hapModulesList) {
6984             auto& abilityInfoList = hapModule.abilityInfos;
6985             for (auto& abilityInfo : abilityInfoList) {
6986                 SCBAbilityInfo scbAbilityInfo;
6987                 scbAbilityInfo.abilityInfo_ = abilityInfo;
6988                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6989                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6990                 scbAbilityInfos.push_back(scbAbilityInfo);
6991             }
6992         }
6993     }
6994     return WSError::WS_OK;
6995 }
6996 
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)6997 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
6998 {
6999     if (abilityInfo.orientationId == 0) {
7000         return;
7001     }
7002     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
7003     if (resConfig == nullptr) {
7004         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
7005         return;
7006     }
7007     std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
7008         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
7009     if (resourceMgr == nullptr) {
7010         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
7011         return;
7012     }
7013     std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
7014     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
7015         TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
7016     }
7017     std::string orientation;
7018     auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
7019     if (ret != Global::Resource::RState::SUCCESS) {
7020         TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
7021             static_cast<int32_t>(ret), abilityInfo.orientationId);
7022         return;
7023     }
7024     if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
7025         TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
7026         return;
7027     }
7028     abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
7029 }
7030 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)7031 WSError SceneSessionManager::TerminateSessionNew(
7032     const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
7033 {
7034     if (info == nullptr) {
7035         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
7036         return WSError::WS_ERROR_INVALID_PARAM;
7037     }
7038     TLOGI(WmsLogTag::WMS_LIFE,
7039         "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
7040         info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
7041     int32_t callingPid = IPCSkeleton::GetCallingPid();
7042     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
7043     auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
7044         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
7045         if (sceneSession == nullptr) {
7046             TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
7047             return WSError::WS_ERROR_INVALID_PARAM;
7048         }
7049         const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
7050         if (!pidCheck &&
7051             !SessionPermission::VerifyPermissionByCallerToken(callerToken,
7052                 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7053             TLOGE(WmsLogTag::WMS_LIFE,
7054                 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
7055                 sceneSession->GetCallingPid(), callingPid);
7056             return WSError::WS_ERROR_INVALID_PERMISSION;
7057         }
7058         WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
7059         return errCode;
7060     };
7061     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
7062 }
7063 
SetVmaCacheStatus(bool flag)7064 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
7065 {
7066     WLOGFI("flag: %{public}d", flag);
7067     RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
7068     return WSError::WS_OK;
7069 }
7070 
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)7071 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
7072                                                 SessionSnapshot& snapshot, bool isLowResolution)
7073 {
7074     WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
7075     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7076         WLOGFE("The caller is not system-app, can not use system-api");
7077         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7078     }
7079     if (!SessionPermission::VerifySessionPermission()) {
7080         WLOGFE("The caller has not permission granted");
7081         return WSError::WS_ERROR_INVALID_PERMISSION;
7082     }
7083     auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
7084         if (CheckIsRemote(deviceId)) {
7085             int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
7086             if (ret != ERR_OK) {
7087                 return WSError::WS_ERROR_INVALID_PARAM;
7088             } else {
7089                 return WSError::WS_OK;
7090             }
7091         }
7092         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7093         if (!sceneSession) {
7094             return WSError::WS_ERROR_INVALID_PARAM;
7095         }
7096         auto sessionInfo = sceneSession->GetSessionInfo();
7097         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7098             WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7099                    sceneSession->GetPersistentId());
7100         }
7101         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
7102         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
7103         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
7104         auto oriSnapshot = sceneSession->Snapshot();
7105         if (oriSnapshot != nullptr) {
7106             if (isLowResolution) {
7107                 OHOS::Media::InitializationOptions options;
7108                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
7109                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
7110                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap
7111                     = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
7112                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
7113             } else {
7114                 snapshot.snapshot = oriSnapshot;
7115             }
7116         }
7117         return WSError::WS_OK;
7118     };
7119     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
7120 }
7121 
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)7122 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
7123 {
7124     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
7125         TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
7126         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7127     }
7128     auto task = [this, persistentId, &snapshot]() {
7129         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7130         if (!sceneSession) {
7131             TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
7132             return WMError::WM_ERROR_INVALID_PARAM;
7133         }
7134         auto sessionInfo = sceneSession->GetSessionInfo();
7135         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7136             TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7137                 sceneSession->GetPersistentId());
7138         }
7139         snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
7140         snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
7141         snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
7142         float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
7143         auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale);
7144         if (oriSnapshot != nullptr) {
7145             if (sceneSession->GetFloatingScale() > 1.0f) {
7146                 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
7147             }
7148             snapshot.snapshot = oriSnapshot;
7149             TLOGI(WmsLogTag::WMS_SYSTEM, "snapshot WxH = %{public}dx%{public}d",
7150                 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
7151             return WMError::WM_OK;
7152         }
7153         return WMError::WM_ERROR_NULLPTR;
7154     };
7155     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
7156 }
7157 
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)7158 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
7159 {
7160     if (!SessionPermission::IsSACalling()) {
7161         TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
7162         return WSError::WS_ERROR_INVALID_PERMISSION;
7163     }
7164     TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
7165     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7166     if (sceneSession == nullptr) {
7167         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
7168         return WSError::WS_ERROR_NULLPTR;
7169     }
7170     return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
7171 }
7172 
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)7173 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
7174                                                       AAFwk::MissionSnapshot& sessionSnapshot)
7175 {
7176     TLOGI(WmsLogTag::DEFAULT, "begin");
7177     int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
7178         sessionId, sessionSnapshot);
7179     if (result != ERR_OK) {
7180         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
7181         return result;
7182     }
7183     return ERR_OK;
7184 }
7185 
GetCollaboratorByType(int32_t collaboratorType)7186 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
7187 {
7188     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
7189     std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
7190     auto iter = collaboratorMap_.find(collaboratorType);
7191     if (iter == collaboratorMap_.end()) {
7192         TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
7193         return collaborator;
7194     }
7195     collaborator = iter->second;
7196     if (collaborator == nullptr) {
7197         TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
7198     }
7199     return collaborator;
7200 }
7201 
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)7202 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
7203 {
7204     wptr<SceneSession> weakSceneSession(sceneSession);
7205     auto task = [this, weakSceneSession]() {
7206         auto scnSession = weakSceneSession.promote();
7207         if (scnSession == nullptr) {
7208             WLOGFE("session is nullptr");
7209             return WSError::WS_ERROR_NULLPTR;
7210         }
7211         auto persistentId = scnSession->GetPersistentId();
7212         if (!GetSceneSession(persistentId)) {
7213             WLOGFE("session is invalid with %{public}d", persistentId);
7214             return WSError::WS_ERROR_INVALID_SESSION;
7215         }
7216         auto sessionInfo = scnSession->GetSessionInfo();
7217         auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
7218         if (!abilitySessionInfo) {
7219             TLOGE(WmsLogTag::WMS_MAIN,
7220                 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
7221             return WSError::WS_ERROR_NULLPTR;
7222         }
7223         TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
7224             sessionInfo.callState_, persistentId);
7225         bool isColdStart = false;
7226         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
7227         if (isColdStart) {
7228             TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
7229                 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
7230             scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
7231             scnSession->ResetSessionConnectState();
7232         }
7233         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
7234         return WSError::WS_OK;
7235     };
7236     std::string taskName = "RequestSceneSessionByCall:PID:" +
7237         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
7238     taskScheduler_->PostAsyncTask(task, taskName);
7239     return WSError::WS_OK;
7240 }
7241 
StartAbilityBySpecified(const SessionInfo & sessionInfo)7242 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
7243 {
7244     auto task = [this, sessionInfo]() {
7245         WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
7246             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
7247         AAFwk::Want want;
7248         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
7249         if (sessionInfo.want != nullptr) {
7250             want.SetParams(sessionInfo.want->GetParams());
7251         }
7252         AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
7253     };
7254 
7255     taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
7256 }
7257 
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)7258 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
7259 {
7260     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
7261     if (pid == -1) {
7262         TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
7263         return;
7264     }
7265     int32_t ret = HiSysEventWrite(
7266         HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
7267         "WINDOW_STATE_ERROR",
7268         HiviewDFX::HiSysEvent::EventType::FAULT,
7269         "PID", pid,
7270         "PERSISTENT_ID", persistentId);
7271     if (ret != 0) {
7272         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
7273     }
7274     auto task = [this, pid] {
7275         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7276         for (const auto& [_, sceneSession] : sceneSessionMap_) {
7277             if (!sceneSession || pid != sceneSession->GetCallingPid() ||
7278                 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7279                 continue;
7280             }
7281             auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
7282             if (abilitySessionInfo) {
7283                 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
7284                     abilitySessionInfo->persistentId);
7285                 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
7286             }
7287         }
7288     };
7289     // delay 2000ms, wait for hidumper
7290     taskScheduler_->PostAsyncTask(task, __func__, 2000);
7291 }
7292 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)7293 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
7294 {
7295     if (!targetToken) {
7296         WLOGFE("Token is null, cannot find main window");
7297         return nullptr;
7298     }
7299 
7300     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7301     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
7302         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7303             if (pair.second->IsTerminated()) {
7304                 return false;
7305             }
7306             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7307                 return pair.second->GetAbilityToken() == targetToken;
7308             }
7309             return false;
7310         });
7311     if (iter == sceneSessionMap_.end()) {
7312         WLOGFE("Cannot find session");
7313         return nullptr;
7314     }
7315     return iter->second;
7316 }
7317 
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)7318 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
7319 {
7320     if (!SessionPermission::IsSystemCalling()) {
7321         TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
7322         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7323     }
7324     if (targetToken == nullptr) {
7325         TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
7326         return WSError::WS_ERROR_NULLPTR;
7327     }
7328 
7329     auto task = [this, persistentId, targetToken]() {
7330         auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
7331         if (scnSession == nullptr) {
7332             TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
7333             return WSError::WS_ERROR_NULLPTR;
7334         }
7335         if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
7336             TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
7337             return WSError::WS_OK;
7338         }
7339         scnSession->dialogTargetToken_ = targetToken;
7340         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
7341         if (parentSession == nullptr) {
7342             scnSession->NotifyDestroy();
7343             return WSError::WS_ERROR_INVALID_PARAM;
7344         }
7345         scnSession->SetParentSession(parentSession);
7346         scnSession->SetParentPersistentId(parentSession->GetPersistentId());
7347         UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
7348         TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
7349             persistentId, parentSession->GetPersistentId());
7350         return WSError::WS_OK;
7351     };
7352     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
7353 }
7354 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7355 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7356     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7357 {
7358     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
7359 }
7360 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7361 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7362     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7363 {
7364     auto isSaCall = SessionPermission::IsSACalling();
7365     if (!isSaCall) {
7366         WLOGFE("The interface only support for sa call");
7367         return WMError::WM_ERROR_INVALID_PERMISSION;
7368     }
7369     auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
7370         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7371         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7372         for (auto missionId : missionIds) {
7373             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
7374             if (iter == sceneSessionMap_.end()) {
7375                 continue;
7376             }
7377             auto sceneSession = iter->second;
7378             if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
7379                 continue;
7380             }
7381             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
7382             if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
7383                 surfaceNodeIds.push_back(missionId);
7384                 continue;
7385             }
7386             if (sceneSession->GetLeashWinSurfaceNode()) {
7387                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
7388             }
7389         }
7390         return WMError::WM_OK;
7391     };
7392     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
7393 }
7394 
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7395 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
7396     const sptr<IWindowManagerAgent>& windowManagerAgent)
7397 {
7398     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7399         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7400         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7401         if (!SessionPermission::IsSystemCalling()) {
7402             WLOGFE("RegisterWindowManagerAgent permission denied!");
7403             return WMError::WM_ERROR_NOT_SYSTEM_APP;
7404         }
7405     } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
7406         if (!SessionPermission::IsSystemServiceCalling()) {
7407             return WMError::WM_ERROR_INVALID_PERMISSION;
7408         }
7409     }
7410     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7411         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7412         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7413         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7414         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7415         if (!SessionPermission::IsSACalling()) {
7416             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7417             return WMError::WM_ERROR_INVALID_PERMISSION;
7418         }
7419     }
7420     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7421         WLOGFE("windowManagerAgent is null");
7422         return WMError::WM_ERROR_NULLPTR;
7423     }
7424     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7425     auto task = [this, windowManagerAgent, type, callingPid]() {
7426         return SessionManagerAgentController::GetInstance()
7427             .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7428     };
7429     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
7430 }
7431 
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7432 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
7433     const sptr<IWindowManagerAgent>& windowManagerAgent)
7434 {
7435     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7436         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7437         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7438         if (!SessionPermission::IsSystemCalling()) {
7439             WLOGFE("UnregisterWindowManagerAgent permission denied!");
7440             return WMError::WM_ERROR_NOT_SYSTEM_APP;
7441         }
7442     }
7443     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7444         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7445         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7446         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7447         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7448         if (!SessionPermission::IsSACalling()) {
7449             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7450             return WMError::WM_ERROR_INVALID_PERMISSION;
7451         }
7452     }
7453     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7454         WLOGFE("windowManagerAgent is null");
7455         return WMError::WM_ERROR_NULLPTR;
7456     }
7457     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7458     auto task = [this, windowManagerAgent, type, callingPid]() {
7459         return SessionManagerAgentController::GetInstance()
7460             .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7461     };
7462     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7463 }
7464 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)7465 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7466 {
7467     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7468 }
7469 
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)7470 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7471 {
7472     SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7473 }
7474 
StartWindowInfoReportLoop()7475 void SceneSessionManager::StartWindowInfoReportLoop()
7476 {
7477     WLOGFD("Report loop");
7478     if (eventHandler_ == nullptr) {
7479         WLOGFE("Report event null");
7480         return ;
7481     }
7482     if (isReportTaskStart_) {
7483         WLOGFE("Report is ReportTask Start");
7484         return;
7485     }
7486     auto task = [this]() {
7487         WindowInfoReporter::GetInstance().ReportRecordedInfos();
7488         ReportWindowProfileInfos();
7489         isReportTaskStart_ = false;
7490         StartWindowInfoReportLoop();
7491     };
7492     int64_t delayTime = 1000 * 60 * 60; // an hour.
7493     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7494     if (!ret) {
7495         WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
7496         return;
7497     }
7498     isReportTaskStart_ = true;
7499 }
7500 
InitPersistentStorage()7501 void SceneSessionManager::InitPersistentStorage()
7502 {
7503     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7504         int32_t storageMode = -1;
7505         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7506         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7507             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7508             WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7509             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7510         }
7511     }
7512 }
7513 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)7514 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7515 {
7516     WLOGFD("Called.");
7517     if (!SessionPermission::IsSystemServiceCalling()) {
7518         WLOGFE("Only support for system service.");
7519         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7520     }
7521     auto task = [this, &infos]() {
7522         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7523         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7524         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7525             sptr<SceneSession> sceneSession = iter->second;
7526             if (sceneSession == nullptr) {
7527                 WLOGFW("null scene session");
7528                 continue;
7529             }
7530             bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7531                 sceneSession->IsVisibleForAccessibility() :
7532                 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7533             WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7534                 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7535                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7536                 sceneSession->GetSessionState(), isVisibleForAccessibility);
7537             if (isVisibleForAccessibility) {
7538                 FillWindowInfo(infos, iter->second);
7539             }
7540         }
7541         return WMError::WM_OK;
7542     };
7543     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7544 }
7545 
CheckUnreliableWindowType(WindowType windowType)7546 static bool CheckUnreliableWindowType(WindowType windowType)
7547 {
7548     if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7549         windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7550         windowType == WindowType::WINDOW_TYPE_TOAST) {
7551         return true;
7552     }
7553     TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7554     return false;
7555 }
7556 
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)7557 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7558     std::vector<sptr<UnreliableWindowInfo>>& infos)
7559 {
7560     if (sceneSession == nullptr) {
7561         TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7562         return;
7563     }
7564     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7565         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7566         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7567         TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7568         return;
7569     }
7570     sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo();
7571     if (info == nullptr) {
7572         TLOGE(WmsLogTag::DEFAULT, "null info.");
7573         return;
7574     }
7575     info->windowId_ = sceneSession->GetPersistentId();
7576     WSRect windowRect = sceneSession->GetSessionRect();
7577     info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7578     info->zOrder_ = sceneSession->GetZOrder();
7579     info->floatingScale_ = sceneSession->GetFloatingScale();
7580     info->scaleX_ = sceneSession->GetScaleX();
7581     info->scaleY_ = sceneSession->GetScaleY();
7582     infos.emplace_back(info);
7583     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7584 }
7585 
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)7586 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
7587     std::vector<sptr<UnreliableWindowInfo>>& infos)
7588 {
7589     TLOGD(WmsLogTag::DEFAULT, "Called.");
7590     if (!SessionPermission::IsSystemServiceCalling()) {
7591         TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
7592         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7593     }
7594     auto task = [this, windowId, &infos]() {
7595         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7596         for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
7597             if (sceneSession == nullptr) {
7598                 TLOGW(WmsLogTag::DEFAULT, "null scene session");
7599                 continue;
7600             }
7601             if (sessionId == windowId) {
7602                 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
7603                 FillUnreliableWindowInfo(sceneSession, infos);
7604                 continue;
7605             }
7606             if (!sceneSession->GetRSVisible()) {
7607                 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
7608                 continue;
7609             }
7610             TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
7611                 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
7612                 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
7613                 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
7614             if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
7615                 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
7616                     "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
7617                 FillUnreliableWindowInfo(sceneSession, infos);
7618             }
7619         }
7620         return WMError::WM_OK;
7621     };
7622     return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
7623 }
7624 
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)7625 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
7626 {
7627     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
7628     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7629     if (sceneSession == nullptr) {
7630         WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
7631         return;
7632     }
7633     wptr<SceneSession> weakSceneSession(sceneSession);
7634     if (processingFlushUIParams_.load()) {
7635         TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
7636         auto task = [this, weakSceneSession, type]() {
7637             auto sceneSession = weakSceneSession.promote();
7638             if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7639                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7640                 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7641             }
7642         };
7643         taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
7644         return;
7645     }
7646     auto task = [this, weakSceneSession, type]() {
7647         auto sceneSession = weakSceneSession.promote();
7648         NotifyAllAccessibilityInfo();
7649         if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7650             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7651             WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7652         }
7653     };
7654     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:id:" + std::to_string(persistentId));
7655 
7656     auto notifySceneInputTask = [weakSceneSession, type]() {
7657         auto sceneSession = weakSceneSession.promote();
7658         if (sceneSession == nullptr) {
7659             return;
7660         }
7661         SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
7662     };
7663     taskScheduler_->PostAsyncTask(notifySceneInputTask);
7664 }
7665 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)7666 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
7667     const sptr<SceneSession>& sceneSession)
7668 {
7669     if (sceneSession == nullptr) {
7670         WLOGFW("null scene session.");
7671         return false;
7672     }
7673     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7674         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7675         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7676         WLOGFD("filter gesture window.");
7677         return false;
7678     }
7679     sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
7680     if (info == nullptr) {
7681         WLOGFE("null info.");
7682         return false;
7683     }
7684     if (sceneSession->GetSessionInfo().isSystem_) {
7685         info->wid_ = 1;
7686         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7687     } else {
7688         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7689     }
7690     info->uiNodeId_ = sceneSession->GetUINodeId();
7691     WSRect wsrect = sceneSession->GetSessionGlobalRect(); // only accessability and mmi need global
7692     info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
7693     info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
7694     info->type_ = sceneSession->GetWindowType();
7695     info->mode_ = sceneSession->GetWindowMode();
7696     info->layer_ = sceneSession->GetZOrder();
7697     info->scaleVal_ = sceneSession->GetFloatingScale();
7698     info->scaleX_ = sceneSession->GetScaleX();
7699     info->scaleY_ = sceneSession->GetScaleY();
7700     info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
7701     info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
7702     auto property = sceneSession->GetSessionProperty();
7703     if (property != nullptr) {
7704         info->displayId_ = property->GetDisplayId();
7705         info->isDecorEnable_ = property->IsDecorEnable();
7706     }
7707     infos.emplace_back(info);
7708     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
7709         info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
7710     return true;
7711 }
7712 
GetSessionSnapshotFilePath(int32_t persistentId)7713 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
7714 {
7715     WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
7716     auto sceneSession = GetSceneSession(persistentId);
7717     if (sceneSession == nullptr) {
7718         WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
7719         return "";
7720     }
7721     wptr<SceneSession> weakSceneSession(sceneSession);
7722     auto task = [this, weakSceneSession]() {
7723         auto scnSession = weakSceneSession.promote();
7724         if (scnSession == nullptr) {
7725             WLOGFE("session is nullptr");
7726             return std::string("");
7727         }
7728         std::string filePath = scnSession->GetSessionSnapshotFilePath();
7729         return filePath;
7730     };
7731     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
7732 }
7733 
SelectSesssionFromMap(const uint64_t & surfaceId)7734 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
7735 {
7736     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7737     for (const auto &item : sceneSessionMap_) {
7738         auto sceneSession = item.second;
7739         if (sceneSession == nullptr) {
7740             continue;
7741         }
7742         if (sceneSession->GetSurfaceNode() == nullptr) {
7743             continue;
7744         }
7745         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
7746             return sceneSession;
7747         }
7748     }
7749     return nullptr;
7750 }
7751 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)7752 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
7753 {
7754     WLOGFD("WindowLayerInfoChangeCallback: entry");
7755     std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
7756 
7757     auto task = [this, weak]() {
7758         auto weakOcclusionData = weak.lock();
7759         if (weakOcclusionData == nullptr) {
7760             WLOGFE("weak occlusionData is nullptr");
7761             return;
7762         }
7763         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
7764         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
7765         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
7766         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
7767         if (currVisibleData.size() != 0) {
7768             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
7769         }
7770         if (visibilityChangeInfos.size() != 0) {
7771             DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
7772             CacVisibleWindowNum();
7773         }
7774 
7775         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
7776         if (currDrawingContentData.size() != 0) {
7777             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
7778         }
7779         if (drawingContentChangeInfos.size() != 0) {
7780             DealwithDrawingContentChange(drawingContentChangeInfos);
7781         }
7782     };
7783     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
7784 }
7785 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)7786 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
7787     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
7788     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
7789 {
7790     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
7791     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
7792         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
7793         switch (windowLayerState) {
7794             case WINDOW_ALL_VISIBLE:
7795             case WINDOW_SEMI_VISIBLE:
7796             case WINDOW_IN_VISIBLE:
7797                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
7798                 break;
7799             case WINDOW_LAYER_DRAWING:
7800                 currDrawingContentData.emplace_back(iter->first, true);
7801                 break;
7802             case WINDOW_LAYER_NO_DRAWING:
7803                 currDrawingContentData.emplace_back(iter->first, false);
7804                 break;
7805             default:
7806                 break;
7807         }
7808     }
7809 }
7810 
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)7811 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
7812     WindowVisibilityState visibleState,
7813     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7814     std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
7815     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7816 {
7817     if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
7818             visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7819         auto subSessions = GetSubSceneSession(session->GetWindowId());
7820         if (subSessions.empty()) {
7821             return;
7822         }
7823 
7824         RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
7825 
7826         for (const auto& subSession : subSessions) {
7827             if (subSession == nullptr) {
7828                 continue;
7829             }
7830             if (session->GetCallingPid() != subSession->GetCallingPid() &&
7831                 (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData))) {
7832                 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
7833                     subSession->GetWindowId());
7834                 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
7835             }
7836         }
7837     }
7838 }
7839 
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7840 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
7841     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7842 {
7843     bool sessionRSVisible = false;
7844     for (const auto& elem : currVisibleData) {
7845         uint64_t surfaceId = elem.first;
7846         WindowVisibilityState visibleState = elem.second;
7847         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7848         sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
7849         if (visibilitySession == nullptr) {
7850             continue;
7851         }
7852         if (session->GetWindowId() == visibilitySession->GetWindowId()) {
7853             if (isVisible) {
7854                 sessionRSVisible = true;
7855             }
7856             break;
7857         }
7858     }
7859     return sessionRSVisible;
7860 }
7861 
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)7862 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
7863     WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
7864     std::string& visibilityInfo)
7865 {
7866     if (session == nullptr) {
7867         TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
7868         return;
7869     }
7870     session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7871     session->SetVisibilityState(visibleState);
7872     int32_t windowId = session->GetWindowId();
7873     if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
7874         session->NotifyWindowVisibility();
7875     }
7876     windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
7877         windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
7878 
7879     visibilityInfo +=
7880         "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
7881 }
7882 
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)7883 void SceneSessionManager::RemoveDuplicateSubSession(
7884     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7885     std::vector<sptr<SceneSession>>& subSessions)
7886 {
7887     for (const auto& elem : visibilityChangeInfo) {
7888         uint64_t surfaceId = elem.first;
7889         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7890         if (session == nullptr) {
7891             continue;
7892         }
7893         for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
7894             auto subSession = *iterator;
7895             if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
7896                 iterator = subSessions.erase(iterator);
7897             } else {
7898                 ++iterator;
7899             }
7900         }
7901     }
7902 }
7903 
GetSubSceneSession(int32_t parentWindowId)7904 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
7905 {
7906     std::vector<sptr<SceneSession>> subSessions;
7907     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7908     for (const auto& iter : sceneSessionMap_) {
7909         auto sceneSession = iter.second;
7910         if (sceneSession == nullptr) {
7911             continue;
7912         }
7913         if (sceneSession->GetParentSession() != nullptr &&
7914             sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
7915             subSessions.push_back(sceneSession);
7916         }
7917     }
7918     return subSessions;
7919 }
7920 
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7921 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
7922     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7923 {
7924     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
7925     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
7926     uint32_t i, j;
7927     i = j = 0;
7928     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
7929         if (lastVisibleData_[i].first < currVisibleData[j].first) {
7930             if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7931                 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7932             }
7933             i++;
7934         } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
7935             if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7936                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7937             }
7938             j++;
7939         } else {
7940             if (lastVisibleData_[i].second != currVisibleData[j].second) {
7941                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7942             }
7943             i++;
7944             j++;
7945         }
7946     }
7947     for (; i < lastVisibleData_.size(); ++i) {
7948         if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7949             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7950         }
7951     }
7952     for (; j < currVisibleData.size(); ++j) {
7953         if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7954             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7955         }
7956     }
7957     lastVisibleData_ = currVisibleData;
7958     return visibilityChangeInfo;
7959 }
7960 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7961 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
7962     visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7963 {
7964     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7965 #ifdef MEMMGR_WINDOW_ENABLE
7966     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7967 #endif
7968 
7969     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
7970     for (const auto& elem : visibilityChangeInfo) {
7971         uint64_t surfaceId = elem.first;
7972         WindowVisibilityState visibleState = elem.second;
7973         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7974         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7975         if (session == nullptr) {
7976             continue;
7977         }
7978         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
7979             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
7980             if (session->GetParentSession() != nullptr &&
7981                 !session->GetParentSession()->IsSessionForeground() &&
7982                 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
7983                 continue;
7984             }
7985         }
7986         SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
7987         UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
7988 #ifdef MEMMGR_WINDOW_ENABLE
7989     memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
7990         session->GetCallingUid(), isVisible));
7991 #endif
7992         CheckAndNotifyWaterMarkChangedResult();
7993     }
7994     if (windowVisibilityInfos.size() != 0) {
7995         WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
7996             visibilityInfo.c_str());
7997         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7998     }
7999 #ifdef MEMMGR_WINDOW_ENABLE
8000     if (memMgrWindowInfos.size() != 0) {
8001         WLOGD("Notify memMgrWindowInfos changed start");
8002         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8003     }
8004 #endif
8005 }
8006 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)8007 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
8008     drawingContentChangeInfo)
8009 {
8010     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
8011     for (const auto& elem : drawingContentChangeInfo) {
8012         uint64_t surfaceId = elem.first;
8013         bool drawingState = elem.second;
8014         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8015         if (session == nullptr) {
8016             continue;
8017         }
8018         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
8019             session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
8020         if (openDebugTrace) {
8021             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
8022                 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
8023         }
8024         WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
8025             "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
8026     }
8027     if (windowDrawingContenInfos.size() != 0) {
8028         WLOGFD("Notify WindowDrawingContenInfo changed start");
8029         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
8030     }
8031 }
8032 
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)8033 WSError SceneSessionManager::NotifyAppUseControlList(
8034     ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
8035 {
8036     TLOGI(WmsLogTag::WMS_LIFE,
8037         "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
8038         static_cast<int>(type), userId, controlList.size());
8039     if (!SessionPermission::IsSACalling()) {
8040         TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8041         return WSError::WS_ERROR_INVALID_PERMISSION;
8042     }
8043     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
8044         TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
8045         return WSError::WS_ERROR_INVALID_PERMISSION;
8046     }
8047     if (currentUserId_ != userId) {
8048         if (currentUserId_ != DEFAULT_USERID) {
8049             TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
8050                 currentUserId_.load(), userId);
8051             return WSError::WS_ERROR_INVALID_OPERATION;
8052         }
8053         int32_t userIdByUid = GetUserIdByUid(getuid());
8054         if (userId != userIdByUid) {
8055             TLOGW(WmsLogTag::WMS_LIFE,
8056                 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
8057                 currentUserId_.load(), userId, userIdByUid);
8058             return WSError::WS_ERROR_INVALID_OPERATION;
8059         }
8060     }
8061     taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
8062         if (notifyAppUseControlListFunc_ != nullptr) {
8063             notifyAppUseControlListFunc_(type, userId, controlList);
8064         }
8065 
8066         std::vector<sptr<SceneSession>> mainSessions;
8067         for (const auto& appUseControlInfo : controlList) {
8068             GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
8069             if (mainSessions.empty()) {
8070                 continue;
8071             }
8072             for (const auto& session : mainSessions) {
8073                 session->NotifyUpdateAppUseControl(type, appUseControlInfo.isNeedControl_);
8074             }
8075             mainSessions.clear();
8076         }
8077     }, __func__);
8078     return WSError::WS_OK;
8079 }
8080 
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)8081 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
8082 {
8083     taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
8084         notifyAppUseControlListFunc_ = std::move(callback);
8085     }, __func__);
8086 }
8087 
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)8088 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
8089     std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
8090 {
8091     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
8092     for (const auto& data : currDrawingContentData) {
8093         uint64_t windowId = data.first;
8094         bool currentDrawingContentState = data.second;
8095         int32_t pid = 0;
8096         bool isChange = false;
8097         if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
8098             continue;
8099         } else {
8100             isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
8101         }
8102         if (isChange) {
8103             processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
8104         }
8105     }
8106     return processDrawingContentChangeInfo;
8107 }
8108 
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)8109 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
8110 {
8111     bool preWindowDrawingState = true;
8112     sptr<SceneSession> session = SelectSesssionFromMap(windowId);
8113     if (session == nullptr) {
8114         return false;
8115     }
8116     pid = session->GetCallingPid();
8117     preWindowDrawingState = session->GetDrawingContentState();
8118     session->SetDrawingContentState(currentDrawingContentState);
8119     return preWindowDrawingState;
8120 }
8121 
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)8122 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
8123 {
8124     bool isChange = true;
8125     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8126     for (const auto& item : sceneSessionMap_) {
8127         auto sceneSession = item.second;
8128         if (sceneSession == nullptr) {
8129             continue;
8130         }
8131         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
8132             windowId != sceneSession->GetSurfaceNode()->GetId()) {
8133             if (sceneSession->GetDrawingContentState()) {
8134                 return false;
8135             }
8136         }
8137     }
8138     return isChange;
8139 }
8140 
InitWithRenderServiceAdded()8141 void SceneSessionManager::InitWithRenderServiceAdded()
8142 {
8143     auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
8144         this->WindowLayerInfoChangeCallback(occlusiontionData);
8145     };
8146     WLOGI("RegisterWindowVisibilityChangeCallback");
8147     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
8148         WLOGFE("RegisterWindowVisibilityChangeCallback failed");
8149     }
8150 }
8151 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)8152 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
8153 {
8154     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
8155         WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
8156         return WMError::WM_ERROR_INVALID_PARAM;
8157     }
8158 
8159     auto task = [this, sceneType]() {
8160         WLOGFD("Set system animated scene %{public}d.", sceneType);
8161         bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
8162         if (!ret) {
8163             WLOGFE("Set system animated scene failed.");
8164         }
8165     };
8166     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
8167     return WMError::WM_OK;
8168 }
8169 
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)8170 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
8171 {
8172     if (!SessionPermission::IsSystemCalling()) {
8173         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
8174         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8175     }
8176     if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
8177         TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
8178         return WSError::WS_ERROR_INVALID_PERMISSION;
8179     }
8180     TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
8181         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
8182     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8183     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
8184         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
8185 	WindowType::WINDOW_TYPE_APP_COMPONENT));
8186     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8187     return WSError::WS_OK;
8188 }
8189 
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)8190 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
8191 {
8192     if (sceneSession == nullptr) {
8193         WLOGFE("sceneSession is nullptr!");
8194         return;
8195     }
8196     if (sceneSession->GetRSVisible()) {
8197         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8198 #ifdef MEMMGR_WINDOW_ENABLE
8199         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
8200 #endif
8201         sceneSession->SetRSVisible(false);
8202         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8203         sceneSession->ClearExtWindowFlags();
8204         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
8205             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
8206             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
8207 #ifdef MEMMGR_WINDOW_ENABLE
8208         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
8209             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
8210 #endif
8211         WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
8212             sceneSession->GetWindowId(), sceneSession->GetRSVisible());
8213         CheckAndNotifyWaterMarkChangedResult();
8214         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8215 #ifdef MEMMGR_WINDOW_ENABLE
8216         WLOGD("Notify memMgrWindowInfos changed start");
8217         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8218 #endif
8219     }
8220 }
8221 
FindSessionByToken(const sptr<IRemoteObject> & token)8222 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
8223 {
8224     if (token == nullptr) {
8225         TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
8226         return nullptr;
8227     }
8228     sptr<SceneSession> session = nullptr;
8229     auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8230         if (pair.second == nullptr) {
8231             return false;
8232         }
8233         return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
8234     };
8235     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8236     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8237     if (iter != sceneSessionMap_.end()) {
8238         session = iter->second;
8239     }
8240     return session;
8241 }
8242 
FindSessionByAffinity(std::string affinity)8243 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
8244 {
8245     if (affinity.size() == 0) {
8246         WLOGFI("AbilityInfo affinity is empty");
8247         return nullptr;
8248     }
8249     sptr<SceneSession> session = nullptr;
8250     auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8251         if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
8252             return false;
8253         }
8254         return pair.second->GetSessionInfo().sessionAffinity == affinity;
8255     };
8256     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8257     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8258     if (iter != sceneSessionMap_.end()) {
8259         session = iter->second;
8260     }
8261     return session;
8262 }
8263 
PreloadInLakeApp(const std::string & bundleName)8264 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
8265 {
8266     WLOGFD("Enter name %{public}s", bundleName.c_str());
8267     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
8268     if (collaborator != nullptr) {
8269         WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
8270         collaborator->NotifyPreloadAbility(bundleName);
8271     }
8272 }
8273 
PendingSessionToForeground(const sptr<IRemoteObject> & token)8274 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
8275 {
8276     TLOGI(WmsLogTag::DEFAULT, "Session is going to foreground");
8277     auto pid = IPCSkeleton::GetCallingRealPid();
8278     if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
8279         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
8280         return WSError::WS_ERROR_INVALID_PERMISSION;
8281     }
8282 
8283     auto task = [this, &token]() {
8284         auto session = FindSessionByToken(token);
8285         if (session != nullptr) {
8286             return session->PendingSessionToForeground();
8287         }
8288         TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
8289         return WSError::WS_ERROR_INVALID_PARAM;
8290     };
8291     return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
8292 }
8293 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)8294 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
8295     bool shouldBackToCaller)
8296 {
8297     auto task = [this, &token, shouldBackToCaller] {
8298         auto session = FindSessionByToken(token);
8299         if (session != nullptr) {
8300             return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
8301         }
8302         TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
8303         return WSError::WS_ERROR_INVALID_PARAM;
8304     };
8305     return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
8306 }
8307 
ClearDisplayStatusBarTemporarilyFlags()8308 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
8309 {
8310     for (auto persistentId : avoidAreaListenerSessionSet_) {
8311         auto sceneSession = GetSceneSession(persistentId);
8312         if (sceneSession == nullptr) {
8313             continue;
8314         }
8315         sceneSession->SetIsDisplayStatusBarTemporarily(false);
8316     }
8317 }
8318 
GetFocusSessionToken(sptr<IRemoteObject> & token)8319 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
8320 {
8321     if (!SessionPermission::IsSACalling()) {
8322         WLOGFE("GetFocusSessionToken permission denied!");
8323         return WSError::WS_ERROR_INVALID_PERMISSION;
8324     }
8325     auto task = [this, &token]() {
8326         WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
8327         auto sceneSession = GetSceneSession(focusedSessionId_);
8328         if (sceneSession) {
8329             token = sceneSession->GetAbilityToken();
8330             if (token == nullptr) {
8331                 WLOGFE("token is nullptr");
8332                 return WSError::WS_ERROR_INVALID_PARAM;
8333             }
8334             return WSError::WS_OK;
8335         }
8336         return WSError::WS_ERROR_INVALID_PARAM;
8337     };
8338     return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
8339 }
8340 
GetFocusSessionElement(AppExecFwk::ElementName & element)8341 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
8342 {
8343     AppExecFwk::RunningProcessInfo info;
8344     auto pid = IPCSkeleton::GetCallingRealPid();
8345     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
8346     if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
8347         WLOGFE("GetFocusSessionElement permission denied!");
8348         return WSError::WS_ERROR_INVALID_PERMISSION;
8349     }
8350     auto task = [this, &element]() {
8351         WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
8352         auto sceneSession = GetSceneSession(focusedSessionId_);
8353         if (sceneSession) {
8354             auto sessionInfo = sceneSession->GetSessionInfo();
8355             element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
8356                 sessionInfo.abilityName_, sessionInfo.moduleName_);
8357             return WSError::WS_OK;
8358         }
8359         return WSError::WS_ERROR_INVALID_SESSION;
8360     };
8361     return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
8362 }
8363 
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)8364 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
8365 {
8366     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8367     auto task = [this, persistentId, haveListener, callingPid]() {
8368         TLOGI(WmsLogTag::WMS_IMMS,
8369             "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
8370             persistentId, haveListener);
8371         auto sceneSession = GetSceneSession(persistentId);
8372         if (sceneSession == nullptr) {
8373             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8374             return WSError::WS_DO_NOTHING;
8375         }
8376         if (callingPid != sceneSession->GetCallingPid()) {
8377             TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
8378             return WSError::WS_ERROR_INVALID_PERMISSION;
8379         }
8380         if (haveListener) {
8381             avoidAreaListenerSessionSet_.insert(persistentId);
8382             UpdateAvoidArea(persistentId);
8383         } else {
8384             lastUpdatedAvoidArea_.erase(persistentId);
8385             avoidAreaListenerSessionSet_.erase(persistentId);
8386         }
8387         return WSError::WS_OK;
8388     };
8389     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
8390 }
8391 
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const sptr<SceneSession> & sceneSession,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)8392 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
8393     const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
8394 {
8395     if (sceneSession == nullptr) {
8396         TLOGI(WmsLogTag::WMS_IMMS, "scene session null no need update avoid area");
8397         return false;
8398     }
8399     if (lastUpdatedAvoidArea_.find(persistentId) == lastUpdatedAvoidArea_.end()) {
8400         lastUpdatedAvoidArea_[persistentId] = {};
8401     }
8402 
8403     bool needUpdate = true;
8404     if (auto iter = lastUpdatedAvoidArea_[persistentId].find(avoidAreaType);
8405         iter != lastUpdatedAvoidArea_[persistentId].end()) {
8406         needUpdate = iter->second != avoidArea;
8407     } else {
8408         if (avoidArea.isEmptyAvoidArea()) {
8409             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}d type %{public}d empty avoid area",
8410                 persistentId, avoidAreaType);
8411             needUpdate = false;
8412             return needUpdate;
8413         }
8414     }
8415     if (needUpdate) {
8416         lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
8417         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
8418     }
8419 
8420     return needUpdate;
8421 }
8422 
UpdateAvoidSessionAvoidArea(WindowType type,bool & needUpdate)8423 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
8424 {
8425     bool ret = true;
8426     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
8427         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
8428     for (auto& persistentId : avoidAreaListenerSessionSet_) {
8429         auto sceneSession = GetSceneSession(persistentId);
8430         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8431             continue;
8432         }
8433         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8434         ret = UpdateSessionAvoidAreaIfNeed(
8435             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8436         needUpdate = needUpdate || ret;
8437     }
8438 
8439     return;
8440 }
8441 
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)8442 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
8443 {
8444     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
8445         !avoidArea.rightRect_.IsUninitializedRect()) {
8446         return false;
8447     }
8448     if (avoidArea.bottomRect_.IsUninitializedRect()) {
8449         return true;
8450     }
8451     if (isVisible &&
8452         (avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) == sessionBottom)) {
8453         return true;
8454     }
8455     return false;
8456 }
8457 
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)8458 void SceneSessionManager::UpdateNormalSessionAvoidArea(
8459     const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
8460 {
8461     bool ret = true;
8462     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8463         TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
8464             persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
8465         needUpdate = false;
8466         return;
8467     }
8468     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8469         TLOGD(WmsLogTag::WMS_IMMS,
8470             "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
8471         needUpdate = false;
8472         return;
8473     }
8474     uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
8475     uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8476     for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
8477         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8478         if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
8479             !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8480                 sceneSession->GetSessionRect().height_)) {
8481             continue;
8482         }
8483         ret = UpdateSessionAvoidAreaIfNeed(
8484             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8485         needUpdate = needUpdate || ret;
8486     }
8487 
8488     return;
8489 }
8490 
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)8491 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
8492 {
8493     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
8494     auto sceneSession = GetSceneSession(windowId);
8495     if (sceneSession == nullptr) {
8496         WLOGFW("window not exist: %{public}d", windowId);
8497         return;
8498     }
8499 
8500     wptr<SceneSession> weakSceneSession(sceneSession);
8501     WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
8502     auto task = [weakSceneSession, startMoving]() -> WSError {
8503         auto scnSession = weakSceneSession.promote();
8504         if (scnSession == nullptr) {
8505             WLOGFW("session is null");
8506             return WSError::WS_ERROR_NULLPTR;
8507         }
8508         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8509         return WSError::WS_OK;
8510     };
8511     return taskScheduler_->PostAsyncTask(task);
8512 }
8513 
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)8514 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
8515     const std::string taskName, const int delayTime)
8516 {
8517     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
8518 }
8519 
UpdateAvoidArea(int32_t persistentId)8520 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8521 {
8522     auto task = [this, persistentId] {
8523         bool needUpdate = false;
8524         auto sceneSession = GetSceneSession(persistentId);
8525         if (sceneSession == nullptr) {
8526             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8527             return;
8528         }
8529         WindowType type = sceneSession->GetWindowType();
8530         if (sceneSession->IsImmersiveType()) {
8531             UpdateAvoidSessionAvoidArea(type, needUpdate);
8532         } else {
8533             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8534         }
8535         if (needUpdate) {
8536             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8537         }
8538         return;
8539     };
8540     taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8541     return;
8542 }
8543 
UpdateAvoidAreaByType(int32_t persistentId,AvoidAreaType type)8544 void SceneSessionManager::UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)
8545 {
8546     auto task = [this, persistentId, type] {
8547         auto sceneSession = GetSceneSession(persistentId);
8548         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8549             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is nullptr or invisible", persistentId);
8550             return;
8551         }
8552         if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8553             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d has no listener, no need update", persistentId);
8554             return;
8555         }
8556         if (sceneSession->IsImmersiveType()) {
8557             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is immersive type", persistentId);
8558             return;
8559         }
8560         auto avoidArea = sceneSession->GetAvoidAreaByType(type);
8561         if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && !CheckAvoidAreaForAINavigationBar(
8562             isAINavigationBarVisible_, avoidArea, sceneSession->GetSessionRect().height_)) {
8563             return;
8564         }
8565         UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, type);
8566     };
8567     taskScheduler_->PostAsyncTask(task, "UpdateAvoidAreaByType:PID:" + std::to_string(persistentId));
8568 }
8569 
UpdateGestureBackEnabled(int32_t persistentId)8570 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8571 {
8572     auto task = [this, persistentId] {
8573         auto sceneSession = GetSceneSession(persistentId);
8574         if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8575             TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8576             return;
8577         }
8578         auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8579         if (needEnableGestureBack) {
8580             gestureBackEnableWindowIdSet_.erase(persistentId);
8581         } else {
8582             gestureBackEnableWindowIdSet_.insert(persistentId);
8583         }
8584         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8585             sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8586             (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8587              sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8588             enterRecent_.load() || !sceneSession->IsFocused()) {
8589             needEnableGestureBack = true;
8590         }
8591         if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8592             gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8593                 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8594         } else {
8595             TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8596         }
8597     };
8598     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8599 }
8600 
UpdateOccupiedAreaIfNeed(const int32_t & persistentId)8601 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8602 {
8603     auto task = [this, persistentId]() {
8604         sptr<SceneSession> keyboardSession = nullptr;
8605         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8606         for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8607             auto sceneSession = item->second;
8608             if (sceneSession != nullptr &&
8609                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8610                 keyboardSession = sceneSession;
8611                 break;
8612             }
8613         }
8614         if (keyboardSession == nullptr) {
8615             TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8616             return;
8617         }
8618         if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8619             return;
8620         }
8621 
8622         keyboardSession->OnCallingSessionUpdated();
8623         return;
8624     };
8625     taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8626     return;
8627 }
8628 
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)8629 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8630 {
8631     TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8632         isVisible, persistentId);
8633     auto task = [this, persistentId, isVisible] {
8634         auto sceneSession = GetSceneSession(persistentId);
8635         if (sceneSession == nullptr) {
8636             TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8637             return;
8638         }
8639         sceneSession->SetIsStatusBarVisible(isVisible);
8640     };
8641     taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8642     return WSError::WS_OK;
8643 }
8644 
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)8645 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8646 {
8647     WLOGFI("isVisible: %{public}u, "
8648         "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8649         isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8650     auto task = [this, isVisible, barArea, displayId]() {
8651         bool isNeedUpdate = true;
8652         {
8653             std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8654             isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8655                 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8656                 currAINavigationBarAreaMap_[displayId] != barArea;
8657             if (isNeedUpdate) {
8658                 isAINavigationBarVisible_ = isVisible;
8659                 currAINavigationBarAreaMap_.clear();
8660                 currAINavigationBarAreaMap_[displayId] = barArea;
8661             }
8662             if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8663                 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8664                 currAINavigationBarAreaMap_[displayId] = WSRect();
8665             }
8666         }
8667         if (isNeedUpdate) {
8668             WLOGFI("NotifyAINavigationBar inner: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8669                 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8670             for (auto persistentId : avoidAreaListenerSessionSet_) {
8671                 NotifySessionAINavigationBarChange(persistentId);
8672             }
8673         }
8674     };
8675     taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
8676     return WSError::WS_OK;
8677 }
8678 
NotifySessionAINavigationBarChange(int32_t persistentId)8679 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
8680 {
8681     auto sceneSession = GetSceneSession(persistentId);
8682     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8683         return;
8684     }
8685     bool isLastFrameLayoutFinished = true;
8686     IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
8687     TLOGI(WmsLogTag::WMS_IMMS, "window [%{public}d] is layout finished: %{public}d",
8688         persistentId, isLastFrameLayoutFinished);
8689     if (isLastFrameLayoutFinished) {
8690         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8691         if (!CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8692             sceneSession->GetSessionRect().height_)) {
8693             return;
8694         }
8695         TLOGI(WmsLogTag::WMS_IMMS, "window [%{public}d] immediate update aibar area %{public}s",
8696             persistentId, avoidArea.ToString().c_str());
8697         UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
8698             AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8699     } else {
8700         sceneSession->MarkAvoidAreaAsDirty();
8701     }
8702 }
8703 
GetAINavigationBarArea(uint64_t displayId)8704 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
8705 {
8706     std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8707     if (currAINavigationBarAreaMap_.count(displayId) == 0) {
8708         return {};
8709     }
8710     return currAINavigationBarAreaMap_[displayId];
8711 }
8712 
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)8713 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
8714 {
8715     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8716     auto task = [this, persistentId, haveListener, callingPid]() {
8717         TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
8718             persistentId, haveListener);
8719         auto sceneSession = GetSceneSession(persistentId);
8720         if (sceneSession == nullptr) {
8721             TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
8722             return WSError::WS_DO_NOTHING;
8723         }
8724         if (callingPid != sceneSession->GetCallingPid()) {
8725             TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
8726             return WSError::WS_ERROR_INVALID_PERMISSION;
8727         }
8728         if (haveListener) {
8729             touchOutsideListenerSessionSet_.insert(persistentId);
8730         } else {
8731             touchOutsideListenerSessionSet_.erase(persistentId);
8732         }
8733         return WSError::WS_OK;
8734     };
8735     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
8736 }
8737 
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)8738 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
8739 {
8740     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
8741     auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
8742         WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
8743             persistentId, haveListener);
8744         auto sceneSession = GetSceneSession(persistentId);
8745         if (sceneSession == nullptr) {
8746             WLOGFD("sceneSession is nullptr.");
8747             return WSError::WS_DO_NOTHING;
8748         }
8749         if (callingPid != sceneSession->GetCallingPid()) {
8750             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
8751             return WSError::WS_ERROR_INVALID_PERMISSION;
8752         }
8753         if (haveListener) {
8754             windowVisibilityListenerSessionSet_.insert(persistentId);
8755             sceneSession->NotifyWindowVisibility();
8756         } else {
8757             windowVisibilityListenerSessionSet_.erase(persistentId);
8758         }
8759         return WSError::WS_OK;
8760     };
8761     return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
8762 }
8763 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)8764 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
8765 {
8766     processVirtualPixelRatioChangeFunc_ = func;
8767     WLOGFI("SetVirtualPixelRatioChangeListener");
8768 }
8769 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8770 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8771     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8772 {
8773     if (displayInfo == nullptr) {
8774         WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
8775         return;
8776     }
8777     auto task = [this, displayInfo]() {
8778         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8779         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
8780             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
8781             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
8782                 displayInfo->GetWidth(), displayInfo->GetHeight()
8783             };
8784             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
8785         }
8786         for (const auto &item : sceneSessionMap_) {
8787             auto scnSession = item.second;
8788             if (scnSession == nullptr) {
8789                 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
8790                 continue;
8791             }
8792             SessionInfo sessionInfo = scnSession->GetSessionInfo();
8793             if (sessionInfo.isSystem_) {
8794                 continue;
8795             }
8796             if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8797                 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
8798                 scnSession->UpdateDensity();
8799                 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
8800                     "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
8801                     scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8802             }
8803         }
8804         UpdateDisplayRegion(displayInfo);
8805         return WSError::WS_OK;
8806     };
8807     taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
8808 }
8809 
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8810 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8811     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8812 {
8813     if (displayInfo == nullptr) {
8814         WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
8815         return;
8816     }
8817     auto task = [this, displayInfo]() {
8818         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8819         for (const auto &item : sceneSessionMap_) {
8820             auto scnSession = item.second;
8821             if (scnSession == nullptr) {
8822                 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
8823                 continue;
8824             }
8825             if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8826                 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
8827                 continue;
8828             }
8829             if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
8830                 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
8831                 scnSession->GetRotation() != displayInfo->GetRotation()) {
8832                 scnSession->UpdateRotationAvoidArea();
8833                 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
8834                     "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
8835                     item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8836             }
8837             scnSession->SetRotation(displayInfo->GetRotation());
8838             scnSession->UpdateOrientation();
8839         }
8840         UpdateDisplayRegion(displayInfo);
8841         return WSError::WS_OK;
8842     };
8843     taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
8844 }
8845 
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)8846 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
8847 {
8848     if (displayInfo == nullptr) {
8849         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
8850         return;
8851     }
8852 
8853     auto task = [displayInfo]() -> WSError {
8854         ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
8855             displayInfo->GetScaleX(),
8856             displayInfo->GetScaleY(),
8857             displayInfo->GetPivotX(),
8858             displayInfo->GetPivotY(),
8859             displayInfo->GetTranslateX(),
8860             displayInfo->GetTranslateY());
8861         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
8862         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
8863         return WSError::WS_OK;
8864     };
8865     return taskScheduler_->PostAsyncTask(task);
8866 }
8867 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8868 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8869     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8870 {
8871     WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
8872     switch (type) {
8873         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
8874             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
8875                 displayInfo, displayInfoMap, type);
8876             break;
8877         }
8878         case DisplayStateChangeType::UPDATE_ROTATION: {
8879             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
8880                 displayInfo, displayInfoMap, type);
8881             break;
8882         }
8883         case DisplayStateChangeType::UPDATE_SCALE: {
8884             SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
8885             break;
8886         }
8887         default:
8888             return;
8889     }
8890 }
8891 
OnScreenshot(DisplayId displayId)8892 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
8893 {
8894     SceneSessionManager::GetInstance().OnScreenshot(displayId);
8895 }
8896 
OnScreenshot(DisplayId displayId)8897 void SceneSessionManager::OnScreenshot(DisplayId displayId)
8898 {
8899     auto task = [this, displayId]() {
8900         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8901         for (const auto& iter : sceneSessionMap_) {
8902             auto sceneSession = iter.second;
8903             if (sceneSession == nullptr) {
8904                 continue;
8905             }
8906             auto state = sceneSession->GetSessionState();
8907             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
8908                 sceneSession->NotifyScreenshot();
8909             }
8910         }
8911     };
8912     taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
8913 }
8914 
ClearSession(int32_t persistentId)8915 WSError SceneSessionManager::ClearSession(int32_t persistentId)
8916 {
8917     WLOGFI("id: %{public}d", persistentId);
8918     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8919         WLOGFE("The caller is not system-app, can not use system-api");
8920         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8921     }
8922     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8923         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8924         return WSError::WS_ERROR_INVALID_PERMISSION;
8925     }
8926     auto task = [this, persistentId]() {
8927         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8928         return ClearSession(sceneSession);
8929     };
8930     taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
8931     return WSError::WS_OK;
8932 }
8933 
ClearSession(sptr<SceneSession> sceneSession)8934 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
8935 {
8936     WLOGFD("Enter");
8937     if (sceneSession == nullptr) {
8938         WLOGFE("session is nullptr");
8939         return WSError::WS_ERROR_INVALID_SESSION;
8940     }
8941     if (!IsSessionClearable(sceneSession)) {
8942         WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
8943         return WSError::WS_ERROR_INVALID_SESSION;
8944     }
8945     const WSError errCode = sceneSession->Clear();
8946     return errCode;
8947 }
8948 
ClearAllSessions()8949 WSError SceneSessionManager::ClearAllSessions()
8950 {
8951     WLOGFD("Enter");
8952     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8953         WLOGFE("The caller is not system-app, can not use system-api");
8954         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8955     }
8956     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8957         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8958         return WSError::WS_ERROR_INVALID_PERMISSION;
8959     }
8960     auto task = [this]() {
8961         std::vector<sptr<SceneSession>> sessionVector;
8962         GetAllClearableSessions(sessionVector);
8963         for (uint32_t i = 0; i < sessionVector.size(); i++) {
8964             ClearSession(sessionVector[i]);
8965         }
8966         return WSError::WS_OK;
8967     };
8968     taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
8969     return WSError::WS_OK;
8970 }
8971 
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)8972 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
8973 {
8974     WLOGFD("Enter");
8975     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8976     for (const auto &item : sceneSessionMap_) {
8977         auto scnSession = item.second;
8978         if (IsSessionClearable(scnSession)) {
8979             sessionVector.push_back(scnSession);
8980         }
8981     }
8982 }
8983 
LockSession(int32_t sessionId)8984 WSError SceneSessionManager::LockSession(int32_t sessionId)
8985 {
8986     WLOGFI("id: %{public}d", sessionId);
8987     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8988         WLOGFE("The caller is not system-app, can not use system-api");
8989         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8990     }
8991     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8992         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8993         return WSError::WS_ERROR_INVALID_PERMISSION;
8994     }
8995     auto task = [this, sessionId]() {
8996         auto sceneSession = GetSceneSession(sessionId);
8997         if (sceneSession == nullptr) {
8998             WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
8999             return WSError::WS_ERROR_INVALID_PARAM;
9000         }
9001         sceneSession->SetSessionInfoLockedState(true);
9002         return WSError::WS_OK;
9003     };
9004     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
9005 }
9006 
UnlockSession(int32_t sessionId)9007 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
9008 {
9009     WLOGFI("id: %{public}d", sessionId);
9010     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9011         WLOGFE("The caller is not system-app, can not use system-api");
9012         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9013     }
9014     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9015         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9016         return WSError::WS_ERROR_INVALID_PERMISSION;
9017     }
9018     auto task = [this, sessionId]() {
9019         auto sceneSession = GetSceneSession(sessionId);
9020         if (sceneSession == nullptr) {
9021             WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
9022             return WSError::WS_ERROR_INVALID_PARAM;
9023         }
9024         sceneSession->SetSessionInfoLockedState(false);
9025         return WSError::WS_OK;
9026     };
9027     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
9028 }
9029 
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)9030 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
9031 {
9032     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9033     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9034         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9035         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9036     }
9037     if (!SessionPermission::VerifySessionPermission()) {
9038         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9039         return WSError::WS_ERROR_INVALID_PERMISSION;
9040     }
9041 
9042     return WSError::WS_OK;
9043 }
9044 
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)9045 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
9046     std::vector<int32_t>& result)
9047 {
9048     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9049     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9050         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9051         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9052     }
9053     if (!SessionPermission::VerifySessionPermission()) {
9054         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9055         return WSError::WS_ERROR_INVALID_PERMISSION;
9056     }
9057 
9058     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
9059     return WSError::WS_OK;
9060 }
9061 
IsSessionClearable(sptr<SceneSession> scnSession)9062 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
9063 {
9064     if (scnSession == nullptr) {
9065         WLOGFI("scnSession is nullptr");
9066         return false;
9067     }
9068     SessionInfo sessionInfo = scnSession->GetSessionInfo();
9069     if (sessionInfo.abilityInfo == nullptr) {
9070         WLOGFI("scnSession abilityInfo is nullptr");
9071         return false;
9072     }
9073     if (sessionInfo.abilityInfo->excludeFromMissions && !scnSession->IsAnco()) {
9074         WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
9075         return false;
9076     }
9077     if (sessionInfo.abilityInfo->unclearableMission) {
9078         WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
9079         return false;
9080     }
9081     if (sessionInfo.isSystem_) {
9082         WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
9083         return false;
9084     }
9085     if (sessionInfo.lockedState) {
9086         WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
9087         return false;
9088     }
9089 
9090     return true;
9091 }
9092 
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)9093 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
9094     const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
9095 {
9096     WLOGFI("type: %{public}d", type);
9097     auto isSaCall = SessionPermission::IsSACalling();
9098     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9099         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9100         return WSError::WS_ERROR_INVALID_PERMISSION;
9101     }
9102     if (!CheckCollaboratorType(type)) {
9103         WLOGFW("collaborator register failed, invalid type.");
9104         return WSError::WS_ERROR_INVALID_TYPE;
9105     }
9106     {
9107         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9108         collaboratorMap_[type] = impl;
9109     }
9110     auto task = [this] {
9111         if (abilityManagerCollaboratorRegisteredFunc_) {
9112             abilityManagerCollaboratorRegisteredFunc_();
9113         }
9114     };
9115     taskScheduler_->PostTask(task, __func__);
9116     return WSError::WS_OK;
9117 }
9118 
UnregisterIAbilityManagerCollaborator(int32_t type)9119 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
9120 {
9121     WLOGFI("type: %{public}d", type);
9122     auto isSaCall = SessionPermission::IsSACalling();
9123     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9124         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9125         return WSError::WS_ERROR_INVALID_PERMISSION;
9126     }
9127     if (!CheckCollaboratorType(type)) {
9128         WLOGFE("collaborator unregister failed, invalid type.");
9129         return WSError::WS_ERROR_INVALID_TYPE;
9130     }
9131     {
9132         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9133         collaboratorMap_.erase(type);
9134     }
9135     return WSError::WS_OK;
9136 }
9137 
CheckCollaboratorType(int32_t type)9138 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
9139 {
9140     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
9141         WLOGFD("type is invalid");
9142         return false;
9143     }
9144     return true;
9145 }
9146 
CheckIfReuseSession(SessionInfo & sessionInfo)9147 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
9148 {
9149     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
9150         sessionInfo.moduleName_);
9151     if (abilityInfo == nullptr) {
9152         WLOGFE("abilityInfo is nullptr!");
9153         return BrokerStates::BROKER_UNKOWN;
9154     }
9155     sessionInfo.abilityInfo = abilityInfo;
9156     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
9157     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
9158         collaboratorType = CollaboratorType::RESERVE_TYPE;
9159     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
9160         collaboratorType = CollaboratorType::OTHERS_TYPE;
9161     }
9162     if (!CheckCollaboratorType(collaboratorType)) {
9163         WLOGFW("checked not collaborator!");
9164         return BrokerStates::BROKER_UNKOWN;
9165     }
9166     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
9167     sessionInfo.collaboratorType_ = collaboratorType;
9168     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9169     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
9170         WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
9171         sessionInfo.reuse = true;
9172     } else {
9173         sessionInfo.reuse = false;
9174     }
9175     WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
9176         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
9177     return resultValue;
9178 }
9179 
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)9180 BrokerStates SceneSessionManager::NotifyStartAbility(
9181     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
9182 {
9183     WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
9184     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9185     if (collaborator == nullptr) {
9186         return BrokerStates::BROKER_UNKOWN;
9187     }
9188     if (sessionInfo.want == nullptr) {
9189         WLOGFI("sessionInfo.want is nullptr, init");
9190         sessionInfo.want = std::make_shared<AAFwk::Want>();
9191         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
9192             sessionInfo.moduleName_);
9193     }
9194     auto accessTokenIDEx = sessionInfo.callingTokenId_;
9195     if (collaborator != nullptr) {
9196         containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
9197             std::chrono::system_clock::now().time_since_epoch()).count();
9198 
9199         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9200         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
9201             WLOGFI("want affinity exit %{public}s.", affinity.c_str());
9202             return BrokerStates::BROKER_UNKOWN;
9203         }
9204         sessionInfo.want->SetParam("oh_persistentId", persistentId);
9205         int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
9206             currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
9207         WLOGFI("collaborator ret: %{public}d", ret);
9208         if (ret == 0) {
9209             return BrokerStates::BROKER_STARTED;
9210         } else {
9211             return BrokerStates::BROKER_NOT_START;
9212         }
9213     }
9214     return BrokerStates::BROKER_UNKOWN;
9215 }
9216 
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)9217 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
9218 {
9219     if (sceneSession == nullptr) {
9220         WLOGFE("sceneSession is nullptr");
9221         return;
9222     }
9223     if (sessionInfo.want == nullptr) {
9224         WLOGFI("sessionInfo.want is nullptr");
9225         return;
9226     }
9227     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9228     if (collaborator == nullptr) {
9229         return;
9230     }
9231     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9232     if (abilitySessionInfo == nullptr) {
9233         WLOGFE("abilitySessionInfo is nullptr");
9234         return;
9235     }
9236     abilitySessionInfo->want = *(sessionInfo.want);
9237     if (collaborator != nullptr) {
9238         int32_t missionId = abilitySessionInfo->persistentId;
9239         std::string bundleName = sessionInfo.bundleName_;
9240         int64_t timestamp = containerStartAbilityTime_;
9241         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
9242         WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
9243             missionId, bundleName.c_str());
9244         collaborator->NotifyMissionCreated(abilitySessionInfo);
9245     }
9246 }
9247 
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)9248 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
9249     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
9250 {
9251     WLOGFD("type: %{public}d", collaboratorType);
9252     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9253     if (collaborator != nullptr) {
9254         WLOGFI("called NotifyLoadAbility");
9255         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
9256     }
9257 }
9258 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)9259 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
9260 {
9261     WLOGFD("Enter");
9262     if (sceneSession == nullptr) {
9263         WLOGFE("sceneSession is nullptr");
9264         return;
9265     }
9266     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9267     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9268     if (collaborator != nullptr) {
9269         WLOGFI("called UpdateMissionInfo");
9270         collaborator->UpdateMissionInfo(abilitySessionInfo);
9271     }
9272 }
9273 
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)9274 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
9275 {
9276     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9277     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9278     if (collaborator != nullptr) {
9279         WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
9280         collaborator->NotifyMoveMissionToForeground(persistentId);
9281     }
9282 }
9283 
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)9284 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
9285 {
9286     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9287     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9288     if (collaborator != nullptr) {
9289         WLOGFI("called NotifyClearMission %{public}d", persistentId);
9290         collaborator->NotifyClearMission(persistentId);
9291     }
9292 }
9293 
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)9294 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
9295 {
9296     if (sceneSession == nullptr) {
9297         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
9298         return false;
9299     }
9300     std::string sessionAffinity;
9301     TLOGI(WmsLogTag::WMS_LIFE, "call");
9302     if (sceneSession->GetSessionInfo().want != nullptr) {
9303         sessionAffinity = sceneSession->GetSessionInfo().want
9304             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9305     }
9306     if (sessionAffinity.empty()) {
9307         TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
9308         BrokerStates notifyReturn = NotifyStartAbility(
9309             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
9310         if (notifyReturn == BrokerStates::BROKER_NOT_START) {
9311             TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
9312             return false;
9313         }
9314     }
9315     if (sceneSession->GetSessionInfo().want != nullptr) {
9316         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
9317             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
9318         TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
9319             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
9320             sceneSession->GetSessionInfo().sessionAffinity.c_str());
9321     } else {
9322         TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
9323     }
9324     return true;
9325 }
9326 
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)9327 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
9328 {
9329     if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
9330         return false;
9331     }
9332     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
9333     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
9334     return true;
9335 }
9336 
AddWindowDragHotArea(uint32_t type,WSRect & area)9337 void SceneSessionManager::AddWindowDragHotArea(uint32_t type, WSRect& area)
9338 {
9339     WLOGFI("type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
9340         "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
9341     SceneSession::AddOrUpdateWindowDragHotArea(type, area);
9342 }
9343 
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)9344 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
9345 {
9346     auto task = [this, persistentId, isMaximize]() -> WSError {
9347         WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
9348         auto sceneSession = GetSceneSession(persistentId);
9349         if (sceneSession == nullptr) {
9350             WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9351             return WSError::WS_ERROR_INVALID_WINDOW;
9352         }
9353         sceneSession->UpdateMaximizeMode(isMaximize);
9354         return WSError::WS_OK;
9355     };
9356     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
9357     return WSError::WS_OK;
9358 }
9359 
GetIsLayoutFullScreen(bool & isLayoutFullScreen)9360 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
9361 {
9362     auto task = [this, &isLayoutFullScreen]() {
9363         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9364         for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9365             auto sceneSession = item->second;
9366             if (sceneSession == nullptr) {
9367                 WLOGFE("Session is nullptr");
9368                 continue;
9369             }
9370             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9371                 continue;
9372             }
9373             auto state = sceneSession->GetSessionState();
9374             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9375                 continue;
9376             }
9377             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9378                 continue;
9379             }
9380             auto property = sceneSession->GetSessionProperty();
9381             if (property == nullptr) {
9382                 WLOGFE("Property is nullptr");
9383                 continue;
9384             }
9385             isLayoutFullScreen = property->IsLayoutFullScreen();
9386             auto persistentId = sceneSession->GetPersistentId();
9387             if (isLayoutFullScreen) {
9388                 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
9389                 return WSError::WS_OK;
9390             } else {
9391                 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
9392             }
9393         }
9394         WLOGFD("No immersive window");
9395         return WSError::WS_OK;
9396     };
9397 
9398     taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
9399     return WSError::WS_OK;
9400 }
9401 
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)9402 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
9403 {
9404     auto scnSession = GetSceneSession(persistentId);
9405     if (!scnSession) {
9406         WLOGFE("session is nullptr");
9407         return WSError::WS_ERROR_INVALID_WINDOW;
9408     }
9409     auto fromScreenId = scnSession->GetSessionInfo().screenId_;
9410     scnSession->SetScreenId(screenId);
9411     auto sessionProperty = scnSession->GetSessionProperty();
9412     if (!sessionProperty) {
9413         WLOGFE("Property is null, synchronous screenId failed");
9414         return WSError::WS_ERROR_NULLPTR;
9415     }
9416     sessionProperty->SetDisplayId(screenId);
9417     WLOGFD("Session move display %{public}" PRIu64 " from %{public}" PRIu64, screenId, fromScreenId);
9418     NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
9419     scnSession->NotifyDisplayMove(fromScreenId, screenId);
9420     scnSession->UpdateDensity();
9421     return WSError::WS_OK;
9422 }
9423 
NotifyStackEmpty(int32_t persistentId)9424 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
9425 {
9426     TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
9427     auto task = [this, persistentId]() {
9428         auto scnSession = GetSceneSession(persistentId);
9429         if (!scnSession) {
9430             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
9431             return WSError::WS_ERROR_INVALID_WINDOW;
9432         }
9433         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
9434         return WSError::WS_OK;
9435     };
9436     taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
9437     return WSError::WS_OK;
9438 }
9439 
OnImmersiveStateChange(bool & immersive)9440 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
9441 {
9442     immersive = SceneSessionManager::GetInstance().GetImmersiveState();
9443 }
9444 
GetImmersiveState()9445 bool SceneSessionManager::GetImmersiveState()
9446 {
9447     return taskScheduler_->PostSyncTask([this, where = __func__] {
9448         bool isPcOrPadFreeMultiWindowMode = false;
9449         IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
9450         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9451         for (const auto& [_, sceneSession] : sceneSessionMap_) {
9452             if (sceneSession == nullptr) {
9453                 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
9454                 continue;
9455             }
9456             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9457                 continue;
9458             }
9459             auto state = sceneSession->GetSessionState();
9460             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9461                 continue;
9462             }
9463             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9464                 continue;
9465             }
9466             if (isPcOrPadFreeMultiWindowMode) {
9467                 if (sceneSession->IsLayoutFullScreen()) {
9468                     return true;
9469                 }
9470                 continue;
9471             }
9472             auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
9473             if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
9474                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
9475                     sceneSession->GetPersistentId());
9476                 return true;
9477             } else {
9478                 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
9479                     sceneSession->GetPersistentId());
9480                 break;
9481             }
9482         }
9483         TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
9484         return false;
9485     }, __func__);
9486 }
9487 
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)9488 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
9489     bool withAnimation)
9490 {
9491     session->NotifySessionForeground(reason, withAnimation);
9492 }
9493 
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)9494 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
9495     bool withAnimation, bool isFromInnerkits)
9496 {
9497     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
9498 }
9499 
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)9500 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
9501 {
9502     auto sceneSession = GetSceneSession(persistentId);
9503     if (sceneSession == nullptr) {
9504         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9505         return WSError::WS_ERROR_INVALID_WINDOW;
9506     }
9507     return sceneSession->UpdateTitleInTargetPos(isShow, height);
9508 }
9509 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9510 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9511 {
9512     WLOGFI("AppAnrListener OnAppDebugStarted");
9513     if (debugInfos.empty()) {
9514         WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9515         return;
9516     }
9517     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
9518 }
9519 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9520 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9521 {
9522     WLOGFI("AppAnrListener OnAppDebugStoped");
9523     if (debugInfos.empty()) {
9524         WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9525         return;
9526     }
9527     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
9528 }
9529 
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)9530 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9531 {
9532     if (!Session::IsScbCoreEnabled()) {
9533         return;
9534     }
9535     if (onFlushUIParamsFunc_ != nullptr) {
9536         onFlushUIParamsFunc_();
9537     }
9538     auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9539         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9540         TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9541         {
9542             std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9543             nextFlushCompletedCV_.notify_all();
9544         }
9545         std::vector<uint32_t> startingAppZOrderList;
9546         processingFlushUIParams_.store(true);
9547         {
9548             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9549             for (const auto& item : sceneSessionMap_) {
9550                 auto sceneSession = item.second;
9551                 if (sceneSession == nullptr) {
9552                     continue;
9553                 }
9554                 if (sceneSession->GetSessionInfo().screenId_ != SCREEN_ID_INVALID &&
9555                     sceneSession->GetSessionInfo().screenId_ != screenId) {
9556                     continue;
9557                 }
9558                 auto iter = uiParams.find(sceneSession->GetPersistentId());
9559                 if (iter != uiParams.end()) {
9560                     if (sceneSession->GetSessionInfo().screenId_ == SCREEN_ID_INVALID) {
9561                         sceneSession->SetScreenIdOnServer(screenId);
9562                     }
9563                     if ((systemConfig_.uiType_ == UI_TYPE_PHONE ||
9564                          (systemConfig_.uiType_ == UI_TYPE_PAD && !systemConfig_.IsFreeMultiWindowMode())) &&
9565                         sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
9566                         startingAppZOrderList.push_back(iter->second.zOrder_);
9567                         sceneSession->SetStartingBeforeVisible(false);
9568                     }
9569                     sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9570                 } else {
9571                     sessionMapDirty_ |= sceneSession->UpdateUIParam();
9572                 }
9573             }
9574         }
9575         processingFlushUIParams_.store(false);
9576 
9577         // post process if dirty
9578         if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9579             static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9580             TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9581             for (const auto& item : uiParams) {
9582                 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f"
9583                     " transY:%{public}f, needSync:%{public}d, intreactive:%{public}d", item.first, item.second.zOrder_,
9584                     item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
9585                     item.second.needSync_, item.second.interactive_);
9586             }
9587             ProcessUpdateLastFocusedAppId(startingAppZOrderList);
9588             ProcessFocusZOrderChange(sessionMapDirty_);
9589             PostProcessFocus();
9590             PostProcessProperty(sessionMapDirty_);
9591             NotifyAllAccessibilityInfo();
9592             AnomalyDetection::SceneZOrderCheckProcess();
9593         } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9594             PostProcessProperty(sessionMapDirty_);
9595         }
9596         FlushWindowInfoToMMI();
9597         sessionMapDirty_ = 0;
9598         {
9599             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9600             for (const auto& item : sceneSessionMap_) {
9601                 auto sceneSession = item.second;
9602                 if (sceneSession == nullptr) {
9603                     continue;
9604                 }
9605                 sceneSession->ResetSizeChangeReasonIfDirty();
9606                 sceneSession->ResetDirtyFlags();
9607                 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9608                     sceneSession->SetUIStateDirty(false);
9609                 }
9610             }
9611         }
9612     };
9613     taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9614 }
9615 
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)9616 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
9617 {
9618     TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu", lastFocusedAppSessionId_,
9619           zOrderList.size());
9620     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || zOrderList.empty()) {
9621         return;
9622     }
9623     auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId_);
9624     if (lastFocusedAppSession == nullptr) {
9625         return;
9626     }
9627     uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
9628     auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
9629         return zOrder > lastFocusedAppZOrder;
9630     });
9631     if (it != zOrderList.end()) {
9632         TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
9633         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
9634     }
9635 }
9636 
ProcessFocusZOrderChange(uint32_t dirty)9637 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
9638 {
9639     if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9640         return;
9641     }
9642     if (systemConfig_.uiType_ != UI_TYPE_PHONE && systemConfig_.uiType_ != UI_TYPE_PAD) {
9643         return;
9644     }
9645     TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9646     auto focusedSession = GetSceneSession(focusedSessionId_);
9647     // only when it's from a high zOrder to a low zOrder
9648     if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9649         focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9650         return;
9651     }
9652     auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9653     if (voiceInteractionSession == nullptr) {
9654         return;
9655     }
9656     TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9657           "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9658           voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9659     if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9660         focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9661         return;
9662     }
9663     RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9664 }
9665 
PostProcessFocus()9666 void SceneSessionManager::PostProcessFocus()
9667 {
9668     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9669     // priority process focus requests from top to bottom
9670     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9671     {
9672         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9673         for (auto& iter : sceneSessionMap_) {
9674             auto session = iter.second;
9675             if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9676                 continue;
9677             }
9678             processingSessions.push_back(iter);
9679         }
9680     }
9681     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
9682         bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
9683             !rhs.second->GetPostProcessFocusState().isFocused_;
9684         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
9685         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
9686         return focusCmp || lhsZOrder > rhsZOrder;
9687     };
9688     std::sort(processingSessions.begin(), processingSessions.end(), cmp);
9689 
9690     // only change focus one time
9691     bool focusChanged = false;
9692     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9693         auto session = iter->second;
9694         if (session == nullptr) {
9695             WLOGFE("session is nullptr");
9696             continue;
9697         }
9698         TLOGD(WmsLogTag::WMS_PIPELINE,
9699             "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
9700             session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
9701             session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
9702         if (focusChanged) {
9703             session->ResetPostProcessFocusState();
9704             continue;
9705         }
9706         WSError ret = WSError::WS_DO_NOTHING;
9707         if (session->GetPostProcessFocusState().isFocused_) {
9708             if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
9709                 ret = RequestSessionFocusImmediately(session->GetPersistentId());
9710             } else {
9711                 ret = RequestSessionFocus(session->GetPersistentId(), true,
9712                                           session->GetPostProcessFocusState().reason_);
9713             }
9714         } else {
9715             ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
9716         }
9717         session->ResetPostProcessFocusState();
9718         // if succeed then end process
9719         if (ret == WSError::WS_OK) {
9720             focusChanged = true;
9721         }
9722     }
9723 }
9724 
PostProcessProperty(uint32_t dirty)9725 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
9726 {
9727     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
9728     if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9729         // only trigger update avoid area
9730         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9731         for (auto& iter : sceneSessionMap_) {
9732             auto session = iter.second;
9733             if (session == nullptr) {
9734                 continue;
9735             }
9736             session->PostProcessNotifyAvoidArea();
9737         }
9738         return;
9739     }
9740 
9741     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9742     {
9743         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9744         for (auto& iter : sceneSessionMap_) {
9745             auto session = iter.second;
9746             if (session == nullptr || !session->GetPostProcessProperty()) {
9747                 continue;
9748             }
9749             processingSessions.push_back(iter);
9750         }
9751     }
9752 
9753     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9754         auto session = iter->second;
9755         if (session == nullptr) {
9756             WLOGFE("session is nullptr");
9757             continue;
9758         }
9759         TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
9760         UpdateForceHideState(session, session->GetSessionProperty(), true);
9761         HandleKeepScreenOn(session, session->IsKeepScreenOn());
9762         UpdatePrivateStateAndNotify(session->GetPersistentId());
9763         if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9764             ProcessSubSessionForeground(session);
9765         }
9766         session->SetPostProcessProperty(false);
9767     }
9768 
9769     // update avoid area
9770     {
9771         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9772         for (auto& iter : sceneSessionMap_) {
9773             auto session = iter.second;
9774             if (session == nullptr) {
9775                 continue;
9776             }
9777             session->PostProcessNotifyAvoidArea();
9778         }
9779     }
9780 }
9781 
9782 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)9783 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
9784 {
9785     WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
9786     auto isSaCall = SessionPermission::IsSACalling();
9787     if (!isSaCall) {
9788         WLOGFE("The interface only support for sa call");
9789         return WSError::WS_ERROR_INVALID_PERMISSION;
9790     }
9791     auto task = [this, persistentId]() {
9792         auto sceneSession = GetSceneSession(persistentId);
9793         if (sceneSession == nullptr) {
9794             WLOGFE("session is nullptr");
9795             return WSError::WS_ERROR_INVALID_SESSION;
9796         }
9797         if (!IsSessionVisibleForeground(sceneSession)) {
9798             WLOGFD("session is not visible!");
9799             return WSError::WS_DO_NOTHING;
9800         }
9801         FocusChangeReason reason = FocusChangeReason::MOVE_UP;
9802         RequestSessionFocus(persistentId, true, reason);
9803         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
9804             sceneSession->RaiseToAppTop();
9805         }
9806         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
9807             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
9808             WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
9809             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9810         }
9811         if (sceneSession == nullptr) {
9812             WLOGFE("parent session is nullptr");
9813             return WSError::WS_ERROR_INVALID_SESSION;
9814         }
9815         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9816             sceneSession->NotifyClick();
9817             return WSError::WS_OK;
9818         } else {
9819             WLOGFE("session is not app main window!");
9820             return WSError::WS_ERROR_INVALID_SESSION;
9821         }
9822     };
9823     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
9824     return WSError::WS_OK;
9825 }
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)9826 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
9827 {
9828     WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
9829     if (sourcePersistentId != focusedSessionId_) {
9830         WLOGFE("source session need be focused");
9831         return WSError::WS_ERROR_INVALID_OPERATION;
9832     }
9833     if (targetPersistentId == focusedSessionId_) {
9834         WLOGFE("target session has been focused");
9835         return WSError::WS_DO_NOTHING;
9836     }
9837     sptr<SceneSession> sourceSession = nullptr;
9838     WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
9839     if (ret != WSError::WS_OK) {
9840         return ret;
9841     }
9842     sptr<SceneSession> targetSession = nullptr;
9843     ret = GetAppMainSceneSession(targetSession, targetPersistentId);
9844     if (ret != WSError::WS_OK) {
9845         return ret;
9846     }
9847     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
9848         WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
9849             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
9850         return WSError::WS_ERROR_INVALID_CALLING;
9851     }
9852     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
9853         return WSError::WS_ERROR_INVALID_CALLING;
9854     }
9855     int32_t callingPid = IPCSkeleton::GetCallingPid();
9856     if (callingPid != targetSession->GetCallingPid()) {
9857         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
9858         return WSError::WS_ERROR_INVALID_CALLING;
9859     }
9860     targetSession->NotifyClick();
9861     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
9862     return RequestSessionFocus(targetPersistentId, false, reason);
9863 }
9864 
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)9865 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
9866 {
9867     sceneSession = GetSceneSession(persistentId);
9868     if (sceneSession == nullptr) {
9869         WLOGFE("session(%{public}d) is nullptr", persistentId);
9870         return WSError::WS_ERROR_INVALID_SESSION;
9871     }
9872     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9873         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
9874             WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
9875             return WSError::WS_ERROR_INVALID_CALLING;
9876         }
9877         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9878         if (sceneSession == nullptr) {
9879             WLOGFE("session(%{public}d) parent is nullptr", persistentId);
9880             return WSError::WS_ERROR_INVALID_SESSION;
9881         }
9882     }
9883     return WSError::WS_OK;
9884 }
9885 
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)9886 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
9887     const float scaleParam)
9888 {
9889     auto sceneSession = GetSceneSession(persistentId);
9890     if (!sceneSession) {
9891         WLOGFE("get scene session is nullptr");
9892         return nullptr;
9893     }
9894 
9895     wptr<SceneSession> weakSceneSession(sceneSession);
9896     auto task = [this, persistentId, scaleParam, weakSceneSession]() {
9897         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
9898         auto scnSession = weakSceneSession.promote();
9899         std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
9900         if (scnSession == nullptr) {
9901             WLOGFE("session is nullptr");
9902             return pixelMap;
9903         }
9904 
9905         if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
9906             scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
9907             pixelMap = scnSession->Snapshot(false, scaleParam);
9908         }
9909         if (!pixelMap) {
9910             WLOGFI("get local snapshot pixelmap start");
9911             pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
9912         }
9913         return pixelMap;
9914     };
9915     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
9916 }
9917 
GetSceneSessionMap()9918 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
9919 {
9920     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
9921     {
9922         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9923         retSceneSessionMap = sceneSessionMap_;
9924     }
9925     EraseIf(retSceneSessionMap, [this](const auto& pair) {
9926         if (pair.second == nullptr) {
9927             return true;
9928         }
9929 
9930         if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
9931             if (pair.second->IsVisible()) {
9932                 return false;
9933             }
9934             return true;
9935         }
9936 
9937         if (pair.second->IsSystemInput()) {
9938             return false;
9939         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
9940             return false;
9941         }
9942 
9943         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
9944             return true;
9945         }
9946         return false;
9947     });
9948     return retSceneSessionMap;
9949 }
9950 
NotifyUpdateRectAfterLayout()9951 void SceneSessionManager::NotifyUpdateRectAfterLayout()
9952 {
9953     auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
9954     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
9955     if (transactionController) {
9956         rsTransaction = transactionController->GetRSTransaction();
9957     }
9958     auto task = [this, rsTransaction]() {
9959         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9960         for (auto& iter: sceneSessionMap_) {
9961             auto sceneSession = iter.second;
9962             if (sceneSession && sceneSession->IsDirtyWindow()) {
9963                 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
9964             }
9965         }
9966     };
9967     // need sync task since animation transcation need
9968     return taskScheduler_->PostAsyncTask(task);
9969 }
9970 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)9971 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
9972 {
9973     if (!SessionPermission::IsSystemCalling()) {
9974         WLOGFE("GetVisibilityWindowInfo permission denied!");
9975         return WMError::WM_ERROR_NOT_SYSTEM_APP;
9976     }
9977     auto task = [this, &infos]() {
9978         for (auto [surfaceId, _] : lastVisibleData_) {
9979             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9980             if (session == nullptr) {
9981                 continue;
9982             }
9983             WSRect hostRect = session->GetSessionRect();
9984             Rect rect = {hostRect.posX_, hostRect.posY_,
9985                          static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
9986             auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
9987                                                 session->GetSessionProperty());
9988             infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
9989                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
9990                 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
9991                 session->IsFocused()));
9992         }
9993         return WMError::WM_OK;
9994     };
9995     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
9996 }
9997 
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)9998 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
9999 {
10000     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10001     for (const auto& [id, session] : sceneSessionMap_) {
10002         if (session == nullptr) {
10003             continue;
10004         }
10005         uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
10006         windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
10007     }
10008 }
10009 
FlushWindowInfoToMMI(const bool forceFlush)10010 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
10011 {
10012     auto task = [this, forceFlush] {
10013         if (isUserBackground_) {
10014             TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
10015             return;
10016         }
10017         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
10018         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
10019     };
10020     taskScheduler_->PostAsyncTask(task);
10021 }
10022 
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)10023 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
10024     int32_t& parentId)
10025 {
10026     // This function should be called in task
10027     auto iter = extSessionInfoMap_.find(token);
10028     if (iter == extSessionInfoMap_.end()) {
10029         return false;
10030     }
10031     persistentId = iter->second.persistentId;
10032     parentId = iter->second.parentId;
10033     return true;
10034 }
10035 
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession)10036 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)
10037 {
10038     auto task = [this, remoteExtSession]() {
10039         auto iter = remoteExtSessionMap_.find(remoteExtSession);
10040         if (iter == remoteExtSessionMap_.end()) {
10041             TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
10042             return;
10043         }
10044         auto abilityToken = iter->second;
10045         int32_t persistentId = INVALID_SESSION_ID;
10046         int32_t parentId = INVALID_SESSION_ID;
10047         if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
10048             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10049             return;
10050         }
10051 
10052         TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
10053             persistentId, parentId);
10054         auto sceneSession = GetSceneSession(parentId);
10055         if (sceneSession != nullptr) {
10056             auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10057             sceneSession->RemoveExtWindowFlags(persistentId);
10058             if (oldFlags.hideNonSecureWindowsFlag) {
10059                 HandleSecureSessionShouldHide(sceneSession);
10060             }
10061             if (oldFlags.waterMarkFlag) {
10062                 CheckAndNotifyWaterMarkChangedResult();
10063             }
10064             if (oldFlags.privacyModeFlag) {
10065                 UpdatePrivateStateAndNotify(parentId);
10066             }
10067             sceneSession->RemoveModalUIExtension(persistentId);
10068             sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
10069             sceneSession->RemoveExtensionTokenInfo(abilityToken);
10070         } else {
10071             ExtensionWindowFlags actions;
10072             actions.SetAllActive();
10073             HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
10074         }
10075         extSessionInfoMap_.erase(iter->second);
10076         remoteExtSessionMap_.erase(iter);
10077     };
10078     taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
10079 }
10080 
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)10081 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
10082 {
10083     auto pid = IPCSkeleton::GetCallingRealPid();
10084     auto task = [this, token, pid, rect]() {
10085         int32_t persistentId = INVALID_SESSION_ID;
10086         int32_t parentId = INVALID_SESSION_ID;
10087         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10088             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10089             return;
10090         }
10091         TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
10092             "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
10093             pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10094         auto parentSession = GetSceneSession(parentId);
10095         if (parentSession) {
10096             auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
10097             auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
10098             Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
10099             ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
10100             TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
10101                 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
10102                 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
10103                 parentSession->GetSessionGlobalRect().ToString().c_str());
10104             parentSession->UpdateModalUIExtension(extensionInfo);
10105         }
10106     };
10107     taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
10108 }
10109 
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)10110 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
10111 {
10112     auto pid = IPCSkeleton::GetCallingRealPid();
10113     auto task = [this, token, pid, posX, posY]() {
10114         int32_t persistentId = INVALID_SESSION_ID;
10115         int32_t parentId = INVALID_SESSION_ID;
10116         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10117             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10118             return;
10119         }
10120         TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
10121             "parentId=%{public}d", pid, persistentId, parentId);
10122         auto parentSession = GetSceneSession(parentId);
10123         if (parentSession) {
10124             auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
10125             if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
10126                 modalUIExtensionEventInfo.value().persistentId == persistentId) {
10127                 parentSession->ProcessPointDownSession(posX, posY);
10128             }
10129         }
10130     };
10131     taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
10132 }
10133 
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId)10134 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
10135     const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)
10136 {
10137     auto pid = IPCSkeleton::GetCallingRealPid();
10138     auto callingTokenId = IPCSkeleton::GetCallingTokenID();
10139     auto task = [this, sessionStage, token, surfaceNodeId, pid, callingTokenId]() {
10140         if (sessionStage == nullptr || token == nullptr) {
10141             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10142             return;
10143         }
10144         auto remoteExtSession = sessionStage->AsObject();
10145         if (remoteExtSession == nullptr) {
10146             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10147             return;
10148         }
10149         if (extensionDeath_ == nullptr) {
10150             TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
10151             return;
10152         }
10153         if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
10154             TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
10155             return;
10156         }
10157 
10158         AAFwk::UIExtensionSessionInfo info;
10159         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
10160         if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
10161             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
10162             return;
10163         }
10164 
10165         int32_t persistentId = info.persistentId;
10166         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
10167         UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
10168         TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
10169             "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
10170             surfaceNodeId, pid);
10171 
10172         remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
10173         extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
10174 
10175         auto parentSession = GetSceneSession(parentId);
10176         if (!parentSession) {
10177             TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
10178             return;
10179         }
10180 
10181         UIExtensionTokenInfo tokenInfo;
10182         tokenInfo.abilityToken = token;
10183         tokenInfo.callingTokenId = callingTokenId;
10184         tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
10185             info.extensionAbilityType);
10186         parentSession->AddExtensionTokenInfo(tokenInfo);
10187         parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
10188         if (usage == UIExtensionUsage::MODAL) {
10189             ExtensionWindowEventInfo extensionInfo {
10190                 .persistentId = persistentId,
10191                 .pid = pid,
10192             };
10193             parentSession->AddModalUIExtension(extensionInfo);
10194         }
10195     };
10196     taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
10197 }
10198 
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token)10199 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
10200     const sptr<IRemoteObject>& token)
10201 {
10202     TLOGI(WmsLogTag::WMS_UIEXT, "called");
10203     auto task = [this, sessionStage, token]() {
10204         if (sessionStage == nullptr || token == nullptr) {
10205             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10206             return;
10207         }
10208         auto remoteExtSession = sessionStage->AsObject();
10209         if (remoteExtSession == nullptr) {
10210             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10211             return;
10212         }
10213         auto iter = remoteExtSessionMap_.find(remoteExtSession);
10214         if (iter == remoteExtSessionMap_.end() || iter->second != token) {
10215             TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
10216             return;
10217         }
10218 
10219         DestroyExtensionSession(remoteExtSession);
10220     };
10221     taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
10222 }
10223 
CalculateCombinedExtWindowFlags()10224 void SceneSessionManager::CalculateCombinedExtWindowFlags()
10225 {
10226     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
10227     combinedExtWindowFlags_.bitData = 0;
10228     for (const auto& iter: extWindowFlagsMap_) {
10229         combinedExtWindowFlags_.bitData |= iter.second.bitData;
10230     }
10231     specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
10232 }
10233 
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10234 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
10235     ExtensionWindowFlags actions)
10236 {
10237     auto iter = extWindowFlagsMap_.find(persistentId);
10238     // Each flag is false when inactive, 0 means all flags are inactive
10239     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
10240     ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
10241     if (newFlags.bitData == 0) {
10242         extWindowFlagsMap_.erase(persistentId);
10243     } else {
10244         extWindowFlagsMap_[persistentId] = newFlags;
10245     }
10246     CalculateCombinedExtWindowFlags();
10247 }
10248 
HideNonSecureFloatingWindows()10249 void SceneSessionManager::HideNonSecureFloatingWindows()
10250 {
10251     bool shouldHide = false;
10252     {
10253         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10254         for (const auto& iter: sceneSessionMap_) {
10255             auto& session = iter.second;
10256             if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
10257                 shouldHide = true;
10258                 break;
10259             }
10260         }
10261     }
10262     if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
10263         TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
10264         shouldHide = true;
10265     }
10266     if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
10267         return;
10268     }
10269 
10270     shouldHideNonSecureFloatingWindows_.store(shouldHide);
10271     for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
10272         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
10273             session->NotifyForceHideChange(shouldHide);
10274             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10275                 session->GetWindowName().c_str(), persistentId, shouldHide);
10276         }
10277     }
10278 }
10279 
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)10280 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
10281 {
10282     // don't let sub-window show when switching secure host window to background
10283     if (!sceneSession->IsSessionForeground()) {
10284         return;
10285     }
10286 
10287     auto parentId = sceneSession->GetPersistentId();
10288     bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
10289     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10290     for (const auto& [persistentId, session] : sceneSessionMap_) {
10291         if (!session) {
10292             continue;
10293         }
10294         auto property = session->GetSessionProperty();
10295         if (!property || property->GetParentPersistentId() != parentId) {
10296             continue;
10297         }
10298 
10299         if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
10300             session->NotifyForceHideChange(shouldHide);
10301             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10302                 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
10303         }
10304     }
10305 }
10306 
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)10307 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
10308 {
10309     if (sceneSession == nullptr) {
10310         TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
10311         return WSError::WS_ERROR_INVALID_SESSION;
10312     }
10313 
10314     HideNonSecureFloatingWindows();
10315     HideNonSecureSubWindows(sceneSession);
10316     return WSError::WS_OK;
10317 }
10318 
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10319 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
10320     ExtensionWindowFlags actions)
10321 {
10322     UpdateSpecialExtWindowFlags(persistentId, flags, actions);
10323     if (actions.waterMarkFlag) {
10324         CheckAndNotifyWaterMarkChangedResult();
10325     }
10326     if (actions.hideNonSecureWindowsFlag) {
10327         HideNonSecureFloatingWindows();
10328     }
10329     if (actions.privacyModeFlag) {
10330         UpdatePrivateStateAndNotifyForAllScreens();
10331     }
10332 }
10333 
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)10334 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
10335 {
10336     TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
10337     if (!SessionPermission::IsSystemCalling()) {
10338         TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
10339         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10340     }
10341     const auto callingPid = IPCSkeleton::GetCallingRealPid();
10342     auto task = [this, persistentId, shouldHide, callingPid]() {
10343         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10344         auto iter = sceneSessionMap_.find(persistentId);
10345         if (iter == sceneSessionMap_.end()) {
10346             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
10347                 persistentId);
10348             return WSError::WS_ERROR_INVALID_SESSION;
10349         }
10350         auto sceneSession = iter->second;
10351         if (sceneSession == nullptr) {
10352             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
10353             return WSError::WS_ERROR_NULLPTR;
10354         }
10355         if (callingPid != sceneSession->GetCallingPid()) {
10356             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
10357             return WSError::WS_ERROR_INVALID_PERMISSION;
10358         }
10359         sceneSession->SetShouldHideNonSecureWindows(shouldHide);
10360         return HandleSecureSessionShouldHide(sceneSession);
10361     };
10362 
10363     taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
10364     return WSError::WS_OK;
10365 }
10366 
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const10367 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
10368 {
10369     auto ret = WSError::WS_OK;
10370     bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
10371     if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
10372         actions.hideNonSecureWindowsFlag = false;
10373         actions.waterMarkFlag = false;
10374         TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
10375         ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
10376     }
10377     auto needPrivacyWindow = actions.privacyModeFlag;
10378     if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
10379         actions.privacyModeFlag = false;
10380         TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
10381         ret = WSError::WS_ERROR_INVALID_PERMISSION;
10382     }
10383     return ret;
10384 }
10385 
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)10386 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
10387     uint32_t extWindowActions)
10388 {
10389     ExtensionWindowFlags actions(extWindowActions);
10390     auto ret = CheckExtWindowFlagsPermission(actions);
10391     if (actions.bitData == 0) {
10392         return ret;
10393     }
10394 
10395     ExtensionWindowFlags flags(extWindowFlags);
10396     auto task = [this, token, flags, actions]() {
10397         int32_t persistentId = INVALID_SESSION_ID;
10398         int32_t parentId = INVALID_SESSION_ID;
10399         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10400             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10401             return WSError::WS_ERROR_INVALID_OPERATION;
10402         }
10403 
10404         TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
10405             "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
10406         auto sceneSession = GetSceneSession(parentId);
10407         if (sceneSession == nullptr) {
10408             TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
10409                 parentId);
10410             HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
10411             return WSError::WS_OK;
10412         }
10413 
10414         auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10415         sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
10416         auto newFlags = sceneSession->GetCombinedExtWindowFlags();
10417         if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
10418             HandleSecureSessionShouldHide(sceneSession);
10419         }
10420         if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
10421             CheckAndNotifyWaterMarkChangedResult();
10422         }
10423         if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
10424             UpdatePrivateStateAndNotify(parentId);
10425         }
10426         return WSError::WS_OK;
10427     };
10428 
10429     taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
10430     return ret;
10431 }
10432 
GetHostWindowRect(int32_t hostWindowId,Rect & rect)10433 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
10434 {
10435     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
10436     if (!SessionPermission::IsSystemCalling()) {
10437         TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
10438         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10439     }
10440     auto task = [this, hostWindowId, &rect]() {
10441         auto sceneSession = GetSceneSession(hostWindowId);
10442         if (sceneSession == nullptr) {
10443             TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
10444             return WSError::WS_ERROR_INVALID_SESSION;
10445         }
10446         WSRect hostRect = sceneSession->GetSessionRect();
10447         rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
10448         return WSError::WS_OK;
10449     };
10450     taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
10451     return WSError::WS_OK;
10452 }
10453 
ReclaimPurgeableCleanMem()10454 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
10455 {
10456 #ifdef MEMMGR_WINDOW_ENABLE
10457     return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
10458 #else
10459     return -1;
10460 #endif
10461 }
10462 
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)10463 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
10464     const std::vector<VisibleWindowNumInfo>& currentInfo)
10465 {
10466     if (lastInfo.size() != currentInfo.size()) {
10467         WLOGFE("last and current info is not Same");
10468         return false;
10469     }
10470     int sizeOfLastInfo = static_cast<int>(lastInfo.size());
10471     for (int i = 0; i < sizeOfLastInfo; i++) {
10472         if (lastInfo[i].displayId != currentInfo[i].displayId ||
10473             lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
10474             WLOGFE("last and current visible window num is not Same");
10475             return false;
10476         }
10477     }
10478     return true;
10479 }
10480 
CacVisibleWindowNum()10481 void SceneSessionManager::CacVisibleWindowNum()
10482 {
10483     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10484     {
10485         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10486         sceneSessionMapCopy = sceneSessionMap_;
10487     }
10488     std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
10489     bool isFullScreen = true;
10490     for (const auto& elem : sceneSessionMapCopy) {
10491         auto curSession = elem.second;
10492         if (curSession == nullptr) {
10493             continue;
10494         }
10495         bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
10496             curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
10497         if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10498             continue;
10499         }
10500 
10501         bool isWindowVisible = curSession->GetRSVisible();
10502         if (isWindowVisible) {
10503             auto windowMode = curSession->GetWindowMode();
10504             if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
10505                 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
10506                 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
10507                 isFullScreen = false;
10508             }
10509             int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
10510             auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10511                 [=](const VisibleWindowNumInfo& info) {
10512                     return (static_cast<int32_t>(info.displayId)) == displayId;
10513             });
10514             if (it == visibleWindowNumInfo.end()) {
10515                 visibleWindowNumInfo.push_back({displayId, 1});
10516             } else {
10517                 it->visibleWindowNum++;
10518             }
10519         }
10520     }
10521     if (isFullScreen) {
10522         std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10523                       [](auto& info) { info.visibleWindowNum = 1; });
10524     }
10525     std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
10526     if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10527         SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10528         lastInfo_ = visibleWindowNumInfo;
10529     }
10530 }
10531 
ReportWindowProfileInfos()10532 void SceneSessionManager::ReportWindowProfileInfos()
10533 {
10534     enum class WindowVisibleState : int32_t {
10535         FOCUSBLE = 0,
10536         VISIBLE,
10537         MINIMIZED,
10538         OCCLUSION
10539     };
10540     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10541     {
10542         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10543         sceneSessionMapCopy = sceneSessionMap_;
10544     }
10545     auto focusWindowId = GetFocusedSessionId();
10546     for (const auto& elem : sceneSessionMapCopy) {
10547         auto curSession = elem.second;
10548         if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10549             curSession->GetWindowType() !=  WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10550             continue;
10551         }
10552         WindowProfileInfo windowProfileInfo;
10553         windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10554         windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10555             curSession->GetSessionProperty()->GetDisplayId());
10556         windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10557         if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10558             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10559         } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10560             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10561         } else if (!curSession->GetRSVisible()) {
10562             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10563         } else {
10564             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10565         }
10566         WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10567         WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10568             "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10569             windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10570             windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10571     }
10572 }
10573 
GetCustomDecorHeight(int32_t persistentId)10574 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10575 {
10576     int32_t height = 0;
10577     auto sceneSession = GetSceneSession(persistentId);
10578     if (sceneSession == nullptr) {
10579         TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10580         return 0;
10581     }
10582     height = sceneSession->GetCustomDecorHeight();
10583     TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10584     return height;
10585 }
10586 
removeFailRecoveredSession()10587 void SceneSessionManager::removeFailRecoveredSession()
10588 {
10589     for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10590         auto sceneSession = GetSceneSession(persistentId);
10591         if (sceneSession == nullptr) {
10592             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10593             continue;
10594         }
10595         if (!sceneSession->IsRecovered()) {
10596             TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10597             continue;
10598         }
10599         const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10600         if (!scnSessionInfo) {
10601             TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr,persistentId = %{public}d", persistentId);
10602             continue;
10603         }
10604         TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10605         sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10606     }
10607     failRecoveredPersistentIdSet_.clear();
10608 }
10609 
GetDisplayRegion(DisplayId displayId)10610 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10611 {
10612     if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10613         return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10614     }
10615     TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10616     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10617     if (display == nullptr) {
10618         TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10619         return nullptr;
10620     }
10621     auto displayInfo = display->GetDisplayInfo();
10622     if (displayInfo == nullptr) {
10623         TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
10624         return nullptr;
10625     }
10626     int32_t displayWidth = displayInfo->GetWidth();
10627     int32_t displayHeight = displayInfo->GetHeight();
10628     if (displayWidth == 0 || displayHeight == 0) {
10629         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10630         return nullptr;
10631     }
10632 
10633     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10634     auto region = std::make_shared<SkRegion>(rect);
10635     displayRegionMap_[displayId] = region;
10636     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10637     return std::make_shared<SkRegion>(rect);
10638 }
10639 
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)10640 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
10641 {
10642     if (displayInfo == nullptr) {
10643         TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
10644         return;
10645     }
10646     auto displayId = displayInfo->GetDisplayId();
10647     int32_t displayWidth = displayInfo->GetWidth();
10648     int32_t displayHeight = displayInfo->GetHeight();
10649     if (displayWidth == 0 || displayHeight == 0) {
10650         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10651         return;
10652     }
10653     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10654     auto region = std::make_shared<SkRegion>(rect);
10655     displayRegionMap_[displayId] = region;
10656     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10657 }
10658 
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)10659 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
10660 {
10661     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10662     for (const auto& item : sceneSessionMap_) {
10663         auto sceneSession = item.second;
10664         if (sceneSession == nullptr) {
10665             continue;
10666         }
10667         if (Session::IsScbCoreEnabled()) {
10668             if (!sceneSession->IsVisibleForAccessibility()) {
10669                 continue;
10670             }
10671         } else {
10672             if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
10673                 continue;
10674             }
10675         }
10676         if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10677             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10678             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10679             continue;
10680         }
10681         sceneSessionList.push_back(sceneSession);
10682     }
10683 }
10684 
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)10685 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
10686     std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
10687 {
10688     for (const auto& sceneSession : sceneSessionList) {
10689         if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
10690             TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
10691         }
10692     }
10693 }
10694 
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)10695 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
10696 {
10697     std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
10698         return a->GetZOrder() > b->GetZOrder();
10699     });
10700     std::vector<sptr<SceneSession>> result;
10701     std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
10702     for (const auto& sceneSession : sceneSessionList) {
10703         if (sceneSession == nullptr) {
10704             TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
10705             continue;
10706         }
10707         auto sessionProperty = sceneSession->GetSessionProperty();
10708         if (sessionProperty == nullptr) {
10709             TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
10710             continue;
10711         }
10712         std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
10713         auto displayId = sessionProperty->GetDisplayId();
10714         if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
10715             unaccountedSpace = unaccountedSpaceMap[displayId];
10716         } else {
10717             unaccountedSpace = GetDisplayRegion(displayId);
10718             if (unaccountedSpace == nullptr) {
10719                 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
10720                 continue;
10721             }
10722             unaccountedSpaceMap[displayId] = unaccountedSpace;
10723         }
10724         WSRect wsRect = sceneSession->GetSessionRect();
10725         SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
10726                               .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
10727         SkRegion windowRegion(windowBounds);
10728         if (unaccountedSpace->quickReject(windowRegion)) {
10729             TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10730                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10731             continue;
10732         }
10733         if (!unaccountedSpace->intersects(windowRegion)) {
10734             TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10735                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10736             continue;
10737         }
10738         result.push_back(sceneSession);
10739         unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
10740         if (unaccountedSpace->isEmpty()) {
10741             break;
10742         }
10743     }
10744     sceneSessionList = result;
10745 }
10746 
NotifyAllAccessibilityInfo()10747 void SceneSessionManager::NotifyAllAccessibilityInfo()
10748 {
10749     if (isUserBackground_) {
10750         TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
10751         return;
10752     }
10753     std::vector<sptr<SceneSession>> sceneSessionList;
10754     GetAllSceneSessionForAccessibility(sceneSessionList);
10755     FilterSceneSessionCovered(sceneSessionList);
10756 
10757     std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
10758     FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
10759 
10760     for (const auto& item : accessibilityInfo) {
10761         TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, \
10762             bundle=%{public}s, bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
10763             item->wid_, item->innerWid_, item->bundleName_.c_str(),
10764             item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
10765         for (const auto& rect : item->touchHotAreas_) {
10766             TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d," \
10767             "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
10768         }
10769     }
10770 
10771     SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
10772         WindowUpdateType::WINDOW_UPDATE_ALL);
10773 }
10774 
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)10775 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
10776     const sptr<WindowSessionProperty>& property)
10777 {
10778     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
10779     if (property == nullptr) {
10780         return windowStatus;
10781     }
10782     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
10783         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
10784         if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
10785             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
10786         }
10787     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
10788         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
10789     } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
10790         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10791     } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
10792         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
10793     }
10794     return windowStatus;
10795 }
10796 
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)10797 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
10798 {
10799     if (!SessionPermission::IsStartedByInputMethod()) {
10800         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10801         return WMError::WM_ERROR_INVALID_PERMISSION;
10802     }
10803     auto scnSession = GetSceneSession(persistentId);
10804     if (scnSession == nullptr) {
10805         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10806         return WMError::WM_ERROR_NULLPTR;
10807     }
10808 
10809     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10810         persistentId, scnSession->GetWindowType());
10811 
10812     auto sessionProperty = scnSession->GetSessionProperty();
10813     if (sessionProperty == nullptr) {
10814         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10815         return WMError::WM_ERROR_INVALID_WINDOW;
10816     }
10817     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10818     auto callingSession = GetSceneSession(callingWindowId);
10819     if (callingSession == nullptr) {
10820         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10821         callingSession = GetSceneSession(focusedSessionId_);
10822         if (callingSession == nullptr) {
10823             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10824             return WMError::WM_ERROR_INVALID_WINDOW;
10825         }
10826     }
10827     if (callingSession->IsSystemSession()) {
10828         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10829     } else {
10830         windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
10831             callingSession->GetSessionProperty());
10832     }
10833     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
10834         persistentId, windowStatus);
10835     return WMError::WM_OK;
10836 }
10837 
GetCallingWindowRect(int32_t persistentId,Rect & rect)10838 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
10839 {
10840     if (!SessionPermission::IsStartedByInputMethod()) {
10841         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10842         return WMError::WM_ERROR_INVALID_PERMISSION;
10843     }
10844     auto scnSession = GetSceneSession(persistentId);
10845     if (scnSession == nullptr) {
10846         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10847         return WMError::WM_ERROR_NULLPTR;
10848     }
10849     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10850         persistentId, scnSession->GetWindowType());
10851     auto sessionProperty = scnSession->GetSessionProperty();
10852     if (sessionProperty == nullptr) {
10853         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10854         return WMError::WM_ERROR_INVALID_WINDOW;
10855     }
10856     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10857     auto callingSession = GetSceneSession(callingWindowId);
10858     if (callingSession == nullptr) {
10859         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10860         callingSession = GetSceneSession(focusedSessionId_);
10861         if (callingSession == nullptr) {
10862             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10863             return WMError::WM_ERROR_INVALID_WINDOW;
10864         }
10865     }
10866     WSRect sessionRect = callingSession->GetSessionRect();
10867     rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
10868     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
10869         "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10870     return WMError::WM_OK;
10871 }
10872 
GetWindowModeType(WindowModeType & windowModeType)10873 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
10874 {
10875     if (!SessionPermission::IsSACalling()) {
10876         WLOGFE("GetWindowModeType permission denied!");
10877         return WMError::WM_ERROR_INVALID_PERMISSION;
10878     }
10879     windowModeType = CheckWindowModeType();
10880     return WMError::WM_OK;
10881 }
10882 
GetWindowStyleType(WindowStyleType & windowStyleType)10883 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
10884 {
10885     if (!SessionPermission::IsSACalling()) {
10886         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10887         return WMError::WM_ERROR_INVALID_PERMISSION;
10888     }
10889     auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
10890     if (isPC) {
10891         windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
10892         return WMError::WM_OK;
10893     }
10894     windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
10895         WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
10896     return WMError::WM_OK;
10897 }
10898 
CheckSceneZOrder()10899 void SceneSessionManager::CheckSceneZOrder()
10900 {
10901     auto task = [this]() {
10902         AnomalyDetection::SceneZOrderCheckProcess();
10903     };
10904     taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
10905 }
10906 
NotifyEnterRecentTask(bool enterRecent)10907 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
10908 {
10909     TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
10910     enterRecent_.store(enterRecent);
10911     SetSystemAnimatedScenes(enterRecent ?
10912         SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
10913     auto task = [this] {
10914         for (auto persistentId : gestureBackEnableWindowIdSet_) {
10915             auto sceneSession = GetSceneSession(persistentId);
10916             if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
10917                 continue;
10918             }
10919             UpdateGestureBackEnabled(persistentId);
10920         }
10921     };
10922     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
10923     return WSError::WS_OK;
10924 }
10925 
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)10926 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
10927 {
10928     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
10929         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
10930         return WMError::WM_ERROR_INVALID_PERMISSION;
10931     }
10932 
10933     if (!topNInfo.empty() || (topNum <= 0)) {
10934         return WMError::WM_ERROR_INVALID_PARAM;
10935     }
10936 
10937     TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
10938     auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
10939         if (session == nullptr) {
10940             return false;
10941         }
10942 
10943         if (topNum == 0) {
10944             return true;
10945         }
10946 
10947         if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
10948             TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
10949             return false;
10950         }
10951 
10952         MainWindowInfo info;
10953         info.pid_ = session->GetCallingPid();
10954         info.bundleName_ = session->GetSessionInfo().bundleName_;
10955         topNInfo.push_back(info);
10956         topNum--;
10957         TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
10958             topNum, info.pid_, info.bundleName_.c_str());
10959         return false;
10960     };
10961     TraverseSessionTree(func, true);
10962 
10963     return WMError::WM_OK;
10964 }
10965 
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)10966 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
10967     int32_t x, int32_t y, std::vector<int32_t>& windowIds)
10968 {
10969     TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
10970           displayId, windowNumber, x, y);
10971     if (displayId == DISPLAY_ID_INVALID) {
10972         TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
10973         return WMError::WM_ERROR_INVALID_PARAM;
10974     }
10975     bool findAllWindow = windowNumber <= 0;
10976     bool checkPoint = (x >= 0 && y >= 0);
10977     std::string callerBundleName = SessionPermission::GetCallingBundleName();
10978     auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
10979         findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
10980         if (session == nullptr) {
10981             return false;
10982         }
10983         auto sessionProperty = session->GetSessionProperty();
10984         if (sessionProperty == nullptr) {
10985             return false;
10986         }
10987         if (!findAllWindow && windowNumber == 0) {
10988             return true;
10989         }
10990         bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
10991         bool isSameDisplayId = sessionProperty->GetDisplayId() == displayId;
10992         bool isRsVisible = session->GetRSVisible();
10993         WSRect windowRect = session->GetSessionRect();
10994         bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
10995         TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
10996                " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
10997                session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
10998                sessionProperty->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
10999         if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
11000             return false;
11001         }
11002         windowIds.emplace_back(session->GetPersistentId());
11003         windowNumber--;
11004         return false;
11005     };
11006     auto task = [this, func = std::move(func)] {
11007         TraverseSessionTree(func, true);
11008         return WMError::WM_OK;
11009     };
11010     return taskScheduler_->PostSyncTask(task, __func__);
11011 }
11012 
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const11013 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
11014 {
11015     if (!infos.empty()) {
11016         TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
11017         return WMError::WM_ERROR_INVALID_PARAM;
11018     }
11019     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11020         TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
11021         return WMError::WM_ERROR_INVALID_PERMISSION;
11022     }
11023     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11024     for (const auto& iter : sceneSessionMap_) {
11025         auto& session = iter.second;
11026         if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
11027             continue;
11028         }
11029         MainWindowInfo info;
11030         auto abilityInfo = session->GetSessionInfo().abilityInfo;
11031         info.pid_ = session->GetCallingPid();
11032         info.bundleName_ = session->GetSessionInfo().bundleName_;
11033         info.persistentId_ = session->GetPersistentId();
11034         if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
11035             TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
11036             info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
11037             infos.push_back(info);
11038         } else if (abilityInfo != nullptr) {
11039             info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
11040             infos.push_back(info);
11041             TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
11042                 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
11043                 info.bundleName_.c_str(), info.bundleType_);
11044         }
11045     }
11046     return WMError::WM_OK;
11047 }
11048 
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)11049 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
11050     std::vector<int32_t>& clearFailedIds)
11051 {
11052     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11053         TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
11054         return WMError::WM_ERROR_INVALID_PERMISSION;
11055     }
11056     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
11057         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
11058         return WMError::WM_ERROR_INVALID_PERMISSION;
11059     }
11060     clearFailedIds.clear();
11061     for (const auto persistentId : persistentIds) {
11062         auto sceneSession = GetSceneSession(persistentId);
11063         if (sceneSession == nullptr) {
11064             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
11065             clearFailedIds.push_back(persistentId);
11066             continue;
11067         }
11068         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11069             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11070             clearFailedIds.push_back(persistentId);
11071             continue;
11072         }
11073         sceneSession->Clear();
11074         TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
11075     }
11076     return WMError::WM_OK;
11077 }
11078 
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)11079 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
11080     bool enable)
11081 {
11082     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
11083         width, height, density, enable);
11084 
11085     DMHookInfo dmHookInfo;
11086     dmHookInfo.width_ = width;
11087     dmHookInfo.height_ = height;
11088     dmHookInfo.density_ = density;
11089     dmHookInfo.rotation_ = 0;
11090     dmHookInfo.enableHookRotation_ = false;
11091     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11092     return WMError::WM_OK;
11093 }
11094 
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)11095 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
11096 {
11097     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
11098         "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
11099         hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
11100 
11101     DMHookInfo dmHookInfo;
11102     dmHookInfo.width_ = hookInfo.width_;
11103     dmHookInfo.height_ = hookInfo.height_;
11104     dmHookInfo.density_ = hookInfo.density_;
11105     dmHookInfo.rotation_ = hookInfo.rotation_;
11106     dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
11107     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11108     return WMError::WM_OK;
11109 }
11110 
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)11111 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
11112 {
11113     SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
11114 }
11115 
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)11116 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
11117 {
11118     ScreenFoldData screenFoldData;
11119     WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
11120     if (ret != WMError::WM_OK) {
11121         return ret;
11122     }
11123     return CheckAndReportScreenFoldStatus(screenFoldData);
11124 }
11125 
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)11126 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
11127     ScreenFoldData& screenFoldData)
11128 {
11129     if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
11130         TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
11131         return WMError::WM_DO_NOTHING;
11132     }
11133 
11134     screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
11135     screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
11136     screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
11137     screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
11138     screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
11139     if (!screenFoldData.GetTypeCThermalWithUtil()) {
11140         TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
11141         return WMError::WM_DO_NOTHING;
11142     }
11143     AppExecFwk::ElementName element = {};
11144     WSError ret = GetFocusSessionElement(element);
11145     if (ret != WSError::WS_OK) {
11146         TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
11147         return WMError::WM_DO_NOTHING;
11148     }
11149     screenFoldData.SetFocusedPkgName(element.GetURI());
11150     return WMError::WM_OK;
11151 }
11152 
CheckAndReportScreenFoldStatus(ScreenFoldData & data)11153 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
11154 {
11155     static ScreenFoldData lastScreenHalfFoldData;
11156     if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11157         lastScreenHalfFoldData = data;
11158         return WMError::WM_DO_NOTHING;
11159     }
11160     WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
11161     if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11162         if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
11163             lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
11164         } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
11165             // if stay at half-fold less than 15s, combine this change with last
11166             data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
11167             data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
11168             data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
11169         }
11170         lastScreenHalfFoldData.SetInvalid();
11171     }
11172     WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
11173     return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
11174         currentScreenFoldStatusReportRet;
11175 }
11176 
11177 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)11178 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
11179 {
11180     if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
11181         return WMError::WM_DO_NOTHING;
11182     }
11183 
11184     int32_t ret = HiSysEventWrite(
11185         OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
11186         "FOLDSCREEN_STATE_CHANGE",
11187         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
11188         "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
11189         "LASTFOLDSTATE", data.currentScreenFoldStatus_,
11190         "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
11191         "STATE", -1,
11192         "TIME", data.currentScreenFoldStatusDuration_,
11193         "ROTATION", data.screenRotation_,
11194         "PACKAGE", data.focusedPackageName_,
11195         "ANGLE", data.postureAngle_,
11196         "TYPECTHERMAL", data.typeCThermal_,
11197         "SCREENTHERMAL", -1,
11198         "SCANGLE", -1,
11199         "ISTENT", -1);
11200     if (ret != 0) {
11201         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
11202         return WMError::WM_DO_NOTHING;
11203     }
11204     return WMError::WM_OK;
11205 }
11206 
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userid)11207 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
11208 {
11209     if (currentUserId_ != static_cast<int32_t>(userid)) {
11210         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64,
11211             currentUserId_.load(), userid);
11212         return;
11213     }
11214     auto secSurfaceInfoMap = secExtensionData->GetSecData();
11215     auto task = [secSurfaceInfoMap]()-> WSError {
11216         SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
11217         return WSError::WS_OK;
11218     };
11219     taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
11220 }
11221 
RegisterSecSurfaceInfoListener()11222 void SceneSessionManager::RegisterSecSurfaceInfoListener()
11223 {
11224     auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
11225         this->UpdateSecSurfaceInfo(secExtensionData, userid);
11226     };
11227     TLOGI(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener");
11228     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
11229         TLOGE(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener failed");
11230     }
11231 }
11232 
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)11233 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
11234     const AppForceLandscapeConfig& config)
11235 {
11236     if (bundleName.empty()) {
11237         TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
11238         return WSError::WS_ERROR_NULLPTR;
11239     }
11240     std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11241     appForceLandscapeMap_[bundleName] = config;
11242     TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
11243         bundleName.c_str(), config.mode_, config.homePage_.c_str());
11244     return WSError::WS_OK;
11245 }
11246 
GetAppForceLandscapeConfig(const std::string & bundleName)11247 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
11248 {
11249     if (bundleName.empty()) {
11250         return {};
11251     }
11252     std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11253     if (appForceLandscapeMap_.empty() ||
11254         appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
11255         TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
11256         return {};
11257     }
11258     return appForceLandscapeMap_[bundleName];
11259 }
11260 
TerminateSessionByPersistentId(int32_t persistentId)11261 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
11262 {
11263     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
11264         TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
11265         return WMError::WM_ERROR_INVALID_PERMISSION;
11266     }
11267     if (!SessionPermission::IsSystemAppCall()) {
11268         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
11269         return WMError::WM_ERROR_NOT_SYSTEM_APP;
11270     }
11271     auto sceneSession = GetSceneSession(persistentId);
11272     if (sceneSession == nullptr) {
11273         TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
11274         return WMError::WM_ERROR_INVALID_PARAM;
11275     }
11276     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11277         TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11278         return WMError::WM_ERROR_INVALID_PARAM;
11279     }
11280     sceneSession->Clear(true);
11281     TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
11282     return WMError::WM_OK;
11283 }
11284 
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)11285 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
11286 {
11287     rootSceneProcessBackEventFunc_ = processBackEventFunc;
11288     TLOGI(WmsLogTag::WMS_EVENT, "called");
11289 }
11290 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)11291 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
11292     const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
11293 {
11294     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11295         TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
11296         return WMError::WM_ERROR_INVALID_PERMISSION;
11297     }
11298 
11299     surfaceNodeIds.clear();
11300     TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
11301     for (auto persistentId : persistentIds) {
11302         TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
11303         auto sceneSession = GetSceneSession(persistentId);
11304         if (sceneSession == nullptr) {
11305             continue;
11306         }
11307         auto callingPid = sceneSession->GetCallingPid();
11308         auto surfaceNode = sceneSession->GetSurfaceNode();
11309         if (surfaceNode != nullptr && callingPid == pid) {
11310             surfaceNodeIds.push_back(surfaceNode->GetId());
11311             auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
11312             if (leashWinSurfaceNode != nullptr) {
11313                 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
11314                 surfaceNodeIds.push_back(persistentId);
11315             }
11316         }
11317     }
11318 
11319     return WMError::WM_OK;
11320 }
11321 
ReleaseForegroundSessionScreenLock()11322 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
11323 {
11324     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11325         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11326         return WMError::WM_ERROR_INVALID_PERMISSION;
11327     }
11328 #ifdef POWER_MANAGER_ENABLE
11329     auto task = [this] {
11330         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11331         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11332             if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
11333                 continue;
11334             }
11335             auto res = sceneSession->keepScreenLock_->UnLock();
11336             if (res != ERR_OK) {
11337                 TLOGNE(WmsLogTag::DEFAULT,
11338                     "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
11339                     persistentId, sceneSession->GetWindowName().c_str(), res);
11340                 return WMError::WM_ERROR_INVALID_OPERATION;
11341             }
11342             TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
11343                 persistentId, sceneSession->GetWindowName().c_str());
11344         }
11345         return WMError::WM_OK;
11346     };
11347     return taskScheduler_->PostSyncTask(task, __func__);
11348 #else
11349     TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
11350     return WMError::WM_OK;
11351 #endif
11352 }
11353 
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)11354 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
11355 {
11356     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
11357     auto task = [this, func] {
11358         closeTargetFloatWindowFunc_ = func;
11359     };
11360     taskScheduler_->PostTask(task, __func__);
11361 }
11362 
CloseTargetFloatWindow(const std::string & bundleName)11363 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
11364 {
11365     if (!SessionPermission::IsSystemServiceCalling(false)) {
11366         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
11367         return WMError::WM_ERROR_INVALID_PERMISSION;
11368     }
11369     auto task = [this, bundleName] {
11370         if (closeTargetFloatWindowFunc_) {
11371             TLOGNI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
11372             closeTargetFloatWindowFunc_(bundleName);
11373         }
11374     };
11375     taskScheduler_->PostTask(task, __func__);
11376     return WMError::WM_OK;
11377 }
11378 
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)11379 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
11380 {
11381     SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
11382 }
11383 
CloseTargetPiPWindow(const std::string & bundleName)11384 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
11385 {
11386     if (!SessionPermission::IsSystemServiceCalling(false)) {
11387         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11388         return WMError::WM_ERROR_INVALID_PERMISSION;
11389     }
11390     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11391     for (const auto& iter : sceneSessionMap_) {
11392         auto& session = iter.second;
11393         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
11394             session->GetSessionInfo().bundleName_ == bundleName) {
11395             session->NotifyCloseExistPipWindow();
11396             break;
11397         }
11398     }
11399     return WMError::WM_OK;
11400 }
11401 
GetCurrentPiPWindowInfo(std::string & bundleName)11402 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
11403 {
11404     if (!SessionPermission::IsSystemServiceCalling(false)) {
11405         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11406         return WMError::WM_ERROR_INVALID_PERMISSION;
11407     }
11408     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11409     for (const auto& iter : sceneSessionMap_) {
11410         auto& session = iter.second;
11411         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
11412             bundleName = session->GetSessionInfo().bundleName_;
11413             return WMError::WM_OK;
11414         }
11415     }
11416     TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
11417     return WMError::WM_OK;
11418 }
11419 
UpdateDarkColorModeToRS()11420 void SceneSessionManager::UpdateDarkColorModeToRS()
11421 {
11422     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
11423     if (appContext == nullptr) {
11424         TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
11425         return;
11426     }
11427     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
11428     if (config == nullptr) {
11429         TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
11430         return;
11431     }
11432     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
11433     bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
11434     bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
11435     TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d",
11436         colorMode.c_str(), ret);
11437 }
11438 
IsPcWindow(bool & isPcWindow)11439 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
11440 {
11441     isPcWindow = (systemConfig_.uiType_ == UI_TYPE_PC);
11442     return WMError::WM_OK;
11443 }
11444 
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)11445 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
11446 {
11447     isPcOrPadFreeMultiWindowMode = (systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.freeMultiWindowEnable_);
11448     return WMError::WM_OK;
11449 }
11450 
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)11451 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
11452     std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
11453 {
11454     if (!SessionPermission::IsSystemCalling()) {
11455         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11456         return WMError::WM_ERROR_INVALID_PERMISSION;
11457     }
11458 
11459     auto task = [this, windowIds, &windowDisplayIdMap] {
11460         for (const uint64_t windowId : windowIds) {
11461             sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
11462             if (session == nullptr) {
11463                 continue;
11464             }
11465             sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
11466             if (sessionProperty == nullptr) {
11467                 continue;
11468             }
11469 			DisplayId displayId = sessionProperty->GetDisplayId();
11470             TLOGNI(WmsLogTag::DEFAULT, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
11471                 windowId, displayId);
11472             windowDisplayIdMap.insert({windowId, displayId});
11473         }
11474         return WMError::WM_OK;
11475     };
11476     return taskScheduler_->PostSyncTask(task, __func__);
11477 }
11478 
IsLastFrameLayoutFinished(bool & isLayoutFinished)11479 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
11480 {
11481     if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
11482         TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
11483         return WSError::WS_ERROR_NULLPTR;
11484     }
11485     isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
11486     return WSError::WS_OK;
11487 }
11488 
IsWindowRectAutoSave(const std::string & key,bool & enabled)11489 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled)
11490 {
11491     std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11492     if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11493         enabled = iter->second;
11494     } else {
11495         enabled = false;
11496     }
11497     return WMError::WM_OK;
11498 }
11499 
SetIsWindowRectAutoSave(const std::string & key,bool enabled)11500 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled)
11501 {
11502     std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11503     if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11504         if (!enabled) {
11505             isWindowRectAutoSaveMap_.erase(key);
11506         } else {
11507             iter->second = enabled;
11508         }
11509     } else {
11510         if (enabled) {
11511             isWindowRectAutoSaveMap_.insert({key, enabled});
11512         }
11513     }
11514 }
11515 
RemoveAppInfo(const std::string & bundleName)11516 void SceneSessionManager::RemoveAppInfo(const std::string& bundleName)
11517 {
11518     AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
11519 }
11520 
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)11521 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
11522 {
11523     if (!SessionPermission::IsSystemServiceCalling()) {
11524         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11525         return WMError::WM_ERROR_INVALID_PERMISSION;
11526     }
11527     const char* const where = __func__;
11528     auto task = [this, persistentId, &hostWindowId, where]() {
11529         hostWindowId = INVALID_WINDOW_ID;
11530         sptr<Session> session = GetSceneSession(persistentId);
11531         while (session && SessionHelper::IsSubWindow(session->GetWindowType()))
11532         {
11533             session = session->GetParentSession();
11534         }
11535         if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
11536             hostWindowId = session->GetPersistentId();
11537         }
11538         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
11539             where, persistentId, hostWindowId);
11540         return WMError::WM_OK;
11541     };
11542     return taskScheduler_->PostSyncTask(task, where);
11543 }
11544 } // namespace OHOS::Rosen