• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "session_manager/include/scene_session_manager.h"
17 
18 #include <ability_context.h>
19 #include <ability_manager_client.h>
20 #include <application_context.h>
21 #include <bundlemgr/launcher_service.h>
22 #include <hisysevent.h>
23 #include <parameters.h>
24 #include <hitrace_meter.h>
25 #include "parameter.h"
26 #include "publish/scb_dump_subscriber.h"
27 
28 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
29 #include <display_power_mgr_client.h>
30 #endif
31 
32 #ifdef POWER_MANAGER_ENABLE
33 #include <power_mgr_client.h>
34 #endif
35 
36 #ifdef RES_SCHED_ENABLE
37 #include "res_type.h"
38 #include "res_sched_client.h"
39 #endif
40 #include "scene_system_ability_listener.h"
41 
42 #include "anr_manager.h"
43 #include "color_parser.h"
44 #include "common/include/session_permission.h"
45 #include "display_manager.h"
46 #include "scene_input_manager.h"
47 #include "session/host/include/main_session.h"
48 #include "session/host/include/scb_system_session.h"
49 #include "session/host/include/scene_persistent_storage.h"
50 #include "session/host/include/session_utils.h"
51 #include "session/host/include/sub_session.h"
52 #include "session_helper.h"
53 #include "window_helper.h"
54 #include "screen_session_manager/include/screen_session_manager_client.h"
55 #include "singleton_container.h"
56 #include "xcollie/watchdog.h"
57 #include "session_manager_agent_controller.h"
58 #include "distributed_client.h"
59 #include "softbus_bus_center.h"
60 #include "perform_reporter.h"
61 #include "anr_manager.h"
62 #include "dms_reporter.h"
63 #include "res_sched_client.h"
64 #include "anomaly_detection.h"
65 #ifdef MEMMGR_WINDOW_ENABLE
66 #include "mem_mgr_client.h"
67 #include "mem_mgr_window_info.h"
68 #endif
69 
70 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
71 #include "sec_comp_enhance_kit.h"
72 #endif
73 
74 #ifdef IMF_ENABLE
75 #include <input_method_controller.h>
76 #endif // IMF_ENABLE
77 
78 namespace OHOS::Rosen {
79 namespace {
80 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
81 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
82 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
83 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
84 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
85 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
86 
87 constexpr const char* KEY_SESSION_ID = "com.ohos.param.sessionId";
88 constexpr uint32_t MAX_BRIGHTNESS = 255;
89 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
90 constexpr int32_t DEFAULT_USERID = -1;
91 constexpr int32_t SCALE_DIMENSION = 2;
92 constexpr int32_t TRANSLATE_DIMENSION = 2;
93 constexpr int32_t ROTAION_DIMENSION = 4;
94 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
95 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
96 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
97 const std::string EMPTY_DEVICE_ID = "";
98 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
99 
100 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
101 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
102 constexpr int VALUE_MAX_WIDTH = 5;
103 constexpr int MAX_RESEND_TIMES = 6;
104 constexpr int ORIEN_MAX_WIDTH = 12;
105 constexpr int OFFSET_MAX_WIDTH = 8;
106 constexpr int SCALE_MAX_WIDTH = 8;
107 constexpr int PID_MAX_WIDTH = 8;
108 constexpr int PARENT_ID_MAX_WIDTH = 6;
109 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
110 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
111 const std::string ARG_DUMP_ALL = "-a";
112 const std::string ARG_DUMP_WINDOW = "-w";
113 const std::string ARG_DUMP_SCREEN = "-s";
114 const std::string ARG_DUMP_DISPLAY = "-d";
115 const std::string ARG_DUMP_PIPLINE = "-p";
116 const std::string ARG_DUMP_SCB = "-b";
117 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
118 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
119 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
120 
121 static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
122 
123 static std::shared_ptr<ScbDumpSubscriber> g_scbSubscriber(nullptr);
124 
GetCurrentTime()125 std::string GetCurrentTime()
126 {
127     struct timespec tn;
128     clock_gettime(CLOCK_REALTIME, &tn);
129     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
130         static_cast<uint64_t>(tn.tv_nsec);
131     return std::to_string(uTime);
132 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)133 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
134 {
135     return a.first < b.first;
136 }
137 
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)138 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
139 {
140     if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
141         value = (*item.intsValue_)[0];
142         return true;
143     }
144     return false;
145 }
146 
147 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
148 public:
149     BundleStatusCallback() = default;
150     virtual ~BundleStatusCallback() = default;
151 
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)152     void OnBundleStateChanged(const uint8_t installType,
153         const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
154 
OnBundleAdded(const std::string & bundleName,const int userId)155     void OnBundleAdded(const std::string& bundleName, const int userId) override
156     {
157         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
158     }
159 
OnBundleUpdated(const std::string & bundleName,const int userId)160     void OnBundleUpdated(const std::string& bundleName, const int userId) override
161     {
162         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
163     }
164 
OnBundleRemoved(const std::string & bundleName,const int userId)165     void OnBundleRemoved(const std::string& bundleName, const int userId) override
166     {
167         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
168     }
169 };
170 } // namespace
171 
CreateInstance()172 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
173 {
174     sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
175     sessionManager->Init();
176     return sessionManager;
177 }
178 
GetInstance()179 SceneSessionManager& SceneSessionManager::GetInstance()
180 {
181     static sptr<SceneSessionManager> instance = CreateInstance();
182     return *instance;
183 }
184 
SceneSessionManager()185 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
186 {
187     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
188     currentUserId_ = DEFAULT_USERID;
189     launcherService_ = new AppExecFwk::LauncherService();
190     if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
191         WLOGFE("Failed to register bundle status callback.");
192     }
193     ScbDumpSubscriber::Subscribe(g_scbSubscriber);
194 }
195 
~SceneSessionManager()196 SceneSessionManager::~SceneSessionManager()
197 {
198     ScbDumpSubscriber::UnSubscribe(g_scbSubscriber);
199 }
200 
Init()201 void SceneSessionManager::Init()
202 {
203     auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
204     bool isScbCoreEnabled = (deviceType == UI_TYPE_PHONE || deviceType == "tablet") &&
205         system::GetParameter("persist.window.scbcore.enable", "1") == "1";
206     Session::SetScbCoreEnabled(isScbCoreEnabled);
207 
208     constexpr uint64_t interval = 5 * 1000; // 5 second
209     if (HiviewDFX::Watchdog::GetInstance().AddThread(
210         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
211         WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
212     }
213 
214     bundleMgr_ = GetBundleManager();
215     LoadWindowSceneXml();
216     sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
217     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
218     InitPrepareTerminateConfig();
219     // create handler for inner command at server
220     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
221     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
222     if (eventHandler_ == nullptr) {
223         WLOGFE("Invalid eventHander");
224         return ;
225     }
226     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
227     if (ret != 0) {
228         WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
229     }
230 
231     listenerController_ = std::make_shared<SessionListenerController>();
232     listenerController_->Init();
233     scbSessionHandler_ = new ScbSessionHandler();
234     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
235     StartWindowInfoReportLoop();
236     WLOGI("SSM init success.");
237     RegisterAppListener();
238     openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
239     isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1")  == "1";
240     SceneInputManager::GetInstance().Init();
241 
242     // MMI window state error check
243     int32_t retCode = MMI::InputManager::GetInstance()->
244         RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
245         this->NotifyWindowStateErrorFromMMI(pid, persistentId);
246     });
247     TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
248     UpdateDarkColorModeToRS();
249 }
250 
InitScheduleUtils()251 void SceneSessionManager::InitScheduleUtils()
252 {
253 #ifdef RES_SCHED_ENABLE
254     SCBThreadInfo threadInfo = {
255         .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
256         .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
257     };
258     std::unordered_map<std::string, std::string> payload {
259         { "pid", threadInfo.scbPid_ },
260         { "tid", threadInfo.scbTid_ },
261         { "uid", threadInfo.scbUid_ },
262         { "bundleName", threadInfo.scbBundleName_ },
263     };
264     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
265     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
266     auto task = [threadInfo = std::move(threadInfo)]() mutable {
267         threadInfo.ssmThreadName_ = "OS_SceneSession";
268         threadInfo.ssmTid_ = std::to_string(gettid());
269         const int32_t userInteraction = 2;
270         std::unordered_map<std::string, std::string> payload{
271             { "pid", threadInfo.scbPid_ },
272             { "tid", threadInfo.ssmTid_ },
273             { "uid", threadInfo.scbUid_ },
274             { "extType", "10002" },
275             { "cgroupPrio", "1" },
276             { "isSa", "0" },
277             { "threadName", threadInfo.ssmThreadName_ }
278         };
279         uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
280         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
281         TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
282         sptr<ISystemAbilityManager> systemAbilityManager =
283             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
284         if (!systemAbilityManager) {
285             TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
286             return;
287         }
288         auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
289         int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
290         if (ret != ERR_OK) {
291             TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
292         }
293     };
294     taskScheduler_->PostAsyncTask(task, "changeQosTask");
295 #endif
296 }
297 
RegisterAppListener()298 void SceneSessionManager::RegisterAppListener()
299 {
300     appAnrListener_ = new (std::nothrow) AppAnrListener();
301     auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
302     if (appMgrClient_ == nullptr) {
303         WLOGFE("appMgrClient_ is nullptr.");
304     } else if (appAnrListener_ == nullptr) {
305         WLOGFE("appAnrListener_ is nullptr.");
306     } else {
307         auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
308         if (flag != ERR_OK) {
309             WLOGFE("Register app debug listener failed.");
310         } else {
311             WLOGFI("Register app debug listener success.");
312         }
313     }
314 }
315 
LoadWindowSceneXml()316 void SceneSessionManager::LoadWindowSceneXml()
317 {
318     if (WindowSceneConfig::LoadConfigXml()) {
319         if (WindowSceneConfig::GetConfig().IsMap()) {
320             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
321         }
322         ConfigWindowSceneXml();
323     } else {
324         WLOGFE("Load window scene xml failed");
325     }
326     ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
327         appWindowSceneConfig_.keyboardAnimationOut_);
328 }
329 
InitPrepareTerminateConfig()330 void SceneSessionManager::InitPrepareTerminateConfig()
331 {
332     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
333     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
334         PREPARE_TERMINATE_ENABLE_SIZE);
335     WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
336     if (retSysParam > 0 && !std::strcmp(value, "true")) {
337         isPrepareTerminateEnable_ = true;
338     }
339 }
340 
ConfigWindowSceneXml()341 void SceneSessionManager::ConfigWindowSceneXml()
342 {
343     const auto& config = WindowSceneConfig::GetConfig();
344     WindowSceneConfig::ConfigItem item = config["windowEffect"];
345     if (item.IsMap()) {
346         ConfigWindowEffect(item);
347     }
348 
349     item = config["decor"];
350     if (item.IsMap()) {
351         ConfigDecor(item);
352     }
353 
354     item = config["backgroundswitch"];
355     if (item.IsInts()) {
356         auto numbers = *item.intsValue_;
357         if (numbers.size() == 1 && numbers[0] == 1) {
358             systemConfig_.backgroundswitch = true;
359         }
360     }
361     WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
362 
363     item = config["defaultWindowMode"];
364     if (item.IsInts()) {
365         auto numbers = *item.intsValue_;
366         if (numbers.size() == 1 &&
367             (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
368              numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
369             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
370         }
371     }
372 
373     item = config["defaultMaximizeMode"];
374     if (item.IsInts()) {
375         auto numbers = *item.intsValue_;
376         if (numbers.size() == 1 &&
377             (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
378             numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
379             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
380         }
381     }
382 
383     item = config["keyboardAnimation"];
384     if (item.IsMap()) {
385         ConfigKeyboardAnimation(item);
386     }
387 
388     item = config["maxFloatingWindowSize"];
389     if (item.IsInts()) {
390         auto numbers = *item.intsValue_;
391         if (numbers.size() == 1) {
392             systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
393         }
394     }
395 
396     item = config["windowAnimation"];
397     if (item.IsMap()) {
398         ConfigWindowAnimation(item);
399     }
400 
401     item = config["startWindowTransitionAnimation"];
402     if (item.IsMap()) {
403         ConfigStartingWindowAnimation(item);
404     }
405     ConfigFreeMultiWindow();
406     ConfigWindowSizeLimits();
407     ConfigSnapshotScale();
408     ConfigWindowSceneXml(config);
409 }
410 
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)411 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
412 {
413     WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
414     if (item.IsMap()) {
415         ConfigSystemUIStatusBar(item);
416     }
417     item = config["uiType"];
418     if (item.IsString()) {
419         systemConfig_.uiType_ = item.stringValue_;
420         appWindowSceneConfig_.uiType_ = item.stringValue_;
421     }
422     item = config["backgroundScreenLock"].GetProp("enable");
423     if (item.IsBool()) {
424         appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
425     }
426     item = config["rotationMode"];
427     if (item.IsString()) {
428         appWindowSceneConfig_.rotationMode_ = item.stringValue_;
429     }
430     item = config["immersive"];
431     if (item.IsMap()) {
432         ConfigWindowImmersive(item);
433     }
434     item = config["supportTypeFloatWindow"].GetProp("enable");
435     if (item.IsBool()) {
436         systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
437     }
438 }
439 
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)440 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
441 {
442     AppWindowSceneConfig config;
443     WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
444     if (item.IsMap()) {
445         if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
446             appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
447                 config.windowImmersive_.desktopStatusBarConfig_;
448         }
449     }
450     item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
451     if (item.IsMap()) {
452         if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
453             appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
454                 config.windowImmersive_.upDownStatusBarConfig_;
455         }
456     }
457     item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
458     if (item.IsMap()) {
459         if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
460             appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
461                 config.windowImmersive_.leftRightStatusBarConfig_;
462         }
463     }
464 }
465 
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)466 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
467     StatusBarConfig& statusBarConfig)
468 {
469     WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
470     if (item.IsBool()) {
471         statusBarConfig.showHide_ = item.boolValue_;
472     }
473     item = config["contentColor"];
474     if (item.IsString()) {
475         statusBarConfig.contentColor_ = item.stringValue_;
476     }
477     item = config["backgroundColor"];
478     if (item.IsString()) {
479         statusBarConfig.backgroundColor_ = item.stringValue_;
480     }
481     return true;
482 }
483 
ConfigFreeMultiWindow()484 void SceneSessionManager::ConfigFreeMultiWindow()
485 {
486     const auto& config = WindowSceneConfig::GetConfig();
487     WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
488     if (freeMultiWindowConfig.IsMap()) {
489         auto supportItem = freeMultiWindowConfig.GetProp("enable");
490         if (supportItem.IsBool()) {
491             systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
492         }
493         auto item = freeMultiWindowConfig["decor"];
494         if (item.IsMap()) {
495             ConfigDecor(item, false);
496         }
497         int32_t param = -1;
498         item = freeMultiWindowConfig["defaultWindowMode"];
499         if (GetSingleIntItem(item, param) &&
500             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
501             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
502             systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
503                 static_cast<WindowMode>(static_cast<uint32_t>(param));
504         }
505         item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
506         if (GetSingleIntItem(item, param) && (param > 0)) {
507             systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
508         }
509     }
510 }
511 
LoadFreeMultiWindowConfig(bool enable)512 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
513 {
514     FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
515     if (enable) {
516         systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
517         systemConfig_.decorModeSupportInfo_ = freeMultiWindowConfig.decorModeSupportInfo_;
518         systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
519     } else {
520         const auto& config = WindowSceneConfig::GetConfig();
521         auto item = config["decor"];
522         if (item.IsMap()) {
523             ConfigDecor(item, true);
524         }
525         int32_t param = -1;
526         item = config["defaultWindowMode"];
527         if (GetSingleIntItem(item, param) &&
528             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
529             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
530             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
531         }
532     }
533     systemConfig_.freeMultiWindowEnable_ = enable;
534 }
535 
GetSystemSessionConfig() const536 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
537 {
538     return systemConfig_;
539 }
540 
SwitchFreeMultiWindow(bool enable)541 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
542 {
543     if (!systemConfig_.freeMultiWindowSupport_) {
544         TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
545         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
546     }
547     LoadFreeMultiWindowConfig(enable);
548     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
549     for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
550         auto sceneSession = item->second;
551         if (sceneSession == nullptr) {
552             continue;
553         }
554         auto property = sceneSession->GetSessionProperty();
555         if (property == nullptr) {
556             continue;
557         }
558         bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
559             property->GetExtensionFlag();
560         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
561             sceneSession->SwitchFreeMultiWindow(enable);
562         }
563     }
564     WindowStyleType type = enable ?
565             WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
566     SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
567     return WSError::WS_OK;
568 }
569 
GetFreeMultiWindowEnableState(bool & enable)570 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
571 {
572     enable = systemConfig_.freeMultiWindowEnable_;
573     return WSError::WS_OK;
574 }
575 
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)576 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
577     const ContinueState& continueState)
578 {
579     TLOGI(WmsLogTag::DEFAULT, "Enter");
580     auto task = [this, token, continueState]() {
581         sptr <SceneSession> sceneSession = FindSessionByToken(token);
582         if (sceneSession == nullptr) {
583             TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
584             return WSError::WS_ERROR_INVALID_PARAM;
585         }
586         sceneSession->SetSessionInfoContinueState(continueState);
587         DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
588             static_cast<AAFwk::ContinueState>(continueState));
589         TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
590             sceneSession->GetPersistentId(), continueState);
591         return WSError::WS_OK;
592     };
593     return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
594 }
595 
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)596 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
597 {
598     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
599     if (item.IsBool()) {
600         if (mainConfig) {
601             systemConfig_.isSystemDecorEnable_ = item.boolValue_;
602         } else {
603             systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
604         }
605         bool decorEnable = item.boolValue_;
606         uint32_t support = 0;
607         std::vector<std::string> supportedModes;
608         item = decorConfig["supportedMode"];
609         if (item.IsStrings()) {
610             supportedModes = *item.stringsValue_;
611         }
612         for (auto mode : supportedModes) {
613             if (mode == "fullscreen") {
614                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
615             } else if (mode == "floating") {
616                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
617             } else if (mode == "pip") {
618                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
619             } else if (mode == "split") {
620                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
621                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
622             } else {
623                 WLOGFW("Invalid supporedMode");
624                 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
625                 break;
626             }
627         }
628         if (mainConfig && item.IsStrings()) {
629             systemConfig_.decorModeSupportInfo_ = support;
630         }
631         if (!mainConfig && item.IsStrings()) {
632             systemConfig_.freeMultiWindowConfig_.decorModeSupportInfo_ = support;
633         }
634     }
635 }
636 
AddAlphaToColor(float alpha,std::string & color)637 static void AddAlphaToColor(float alpha, std::string& color)
638 {
639     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
640         return;
641     }
642 
643     uint32_t alphaValue = 0xFF * alpha;
644     std::stringstream ss;
645     ss << std::hex << alphaValue;
646     std::string strAlpha = ss.str();
647     if (strAlpha.size() == 1) {
648         strAlpha.append(1, '0');
649     }
650 
651     color.insert(1, strAlpha);
652 }
653 
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)654 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
655 {
656     return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
657         (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
658         AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
659 }
660 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)661 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
662 {
663     AppWindowSceneConfig config;
664     // config corner radius
665     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
666     if (item.IsMap()) {
667         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
668             appWindowSceneConfig_ = config;
669         }
670     }
671 
672     // config shadow
673     item = effectConfig["appWindows"]["shadow"]["focused"];
674     if (item.IsMap()) {
675         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
676             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
677         }
678     }
679 
680     item = effectConfig["appWindows"]["shadow"]["unfocused"];
681     if (item.IsMap()) {
682         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
683             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
684         }
685     }
686 
687     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
688     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
689 
690     WLOGFI("Config window effect successfully");
691 }
692 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)693 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
694 {
695     std::map<std::string, float> stringToCornerRadius = {
696         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
697         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
698     };
699 
700     if (item.IsString()) {
701         auto value = item.stringValue_;
702         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
703             out = stringToCornerRadius[value];
704             return true;
705         }
706     }
707     return false;
708 }
709 
SetEnableInputEvent(bool enabled)710 void SceneSessionManager::SetEnableInputEvent(bool enabled)
711 {
712     TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
713     enableInputEvent_ = enabled;
714 }
715 
IsInputEventEnabled()716 bool SceneSessionManager::IsInputEventEnabled()
717 {
718     return enableInputEvent_;
719 }
720 
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)721 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
722 {
723     for (const auto& persistentId : alivePersistentIds_) {
724         auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
725         if (it != recoveredPersistentIds.end()) {
726             continue;
727         }
728         auto sceneSession = GetSceneSession(persistentId);
729         if (sceneSession == nullptr) {
730             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
731             continue;
732         }
733         if (sceneSession->IsRecovered()) {
734             TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
735             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
736             EraseSceneSessionAndMarkDirtyLocked(persistentId);
737         }
738     }
739 }
740 
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)741 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
742 {
743     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
744         recoveredPersistentIds.size(), currentUserId_);
745 
746     auto task = [this, recoveredPersistentIds]() {
747         ClearUnrecoveredSessions(recoveredPersistentIds);
748         std::list<AAFwk::SessionInfo> abilitySessionInfos;
749         for (const auto& persistentId : recoveredPersistentIds) {
750             if (failRecoveredPersistentIdSet_.count(persistentId)) {
751                 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
752                 continue;
753             }
754             auto sceneSession = GetSceneSession(persistentId);
755             if (sceneSession == nullptr) {
756                 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
757                 continue;
758             }
759             const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
760             if (!abilitySessionInfo) {
761                 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
762                 continue;
763             }
764             TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
765             abilitySessionInfos.emplace_back(*abilitySessionInfo);
766         }
767         std::vector<int32_t> unrecoverableSessionIds;
768         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
769             abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
770         TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
771             unrecoverableSessionIds.size());
772         for (const auto& sessionId : unrecoverableSessionIds) {
773             auto sceneSession = GetSceneSession(sessionId);
774             if (sceneSession == nullptr) {
775                 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
776                     sessionId);
777                 continue;
778             }
779             const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
780             if (!scnSessionInfo) {
781                 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
782                 continue;
783             }
784             TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
785             sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
786         }
787         removeFailRecoveredSession();
788     };
789     return taskScheduler_->PostAsyncTask(task);
790 }
791 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)792 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
793     WindowShadowConfig& outShadow)
794 {
795     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
796     if (item.IsString()) {
797         auto color = item.stringValue_;
798         uint32_t colorValue;
799         if (!ColorParser::Parse(color, colorValue)) {
800             return false;
801         }
802         outShadow.color_ = color;
803     }
804 
805     item = shadowConfig["offsetX"];
806     if (item.IsFloats()) {
807         auto offsetX = *item.floatsValue_;
808         if (offsetX.size() != 1) {
809             return false;
810         }
811         outShadow.offsetX_ = offsetX[0];
812     }
813 
814     item = shadowConfig["offsetY"];
815     if (item.IsFloats()) {
816         auto offsetY = *item.floatsValue_;
817         if (offsetY.size() != 1) {
818             return false;
819         }
820         outShadow.offsetY_ = offsetY[0];
821     }
822 
823     item = shadowConfig["alpha"];
824     if (item.IsFloats()) {
825         auto alpha = *item.floatsValue_;
826         if (alpha.size() != 1 ||
827             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
828             return false;
829         }
830         outShadow.alpha_ = alpha[0];
831     }
832 
833     item = shadowConfig["radius"];
834     if (item.IsFloats()) {
835         auto radius = *item.floatsValue_;
836         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
837             return false;
838         }
839         outShadow.radius_ = radius[0];
840     }
841 
842     return true;
843 }
844 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)845 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
846     KeyboardSceneAnimationConfig& config)
847 {
848     if (item.IsMap() && item.mapValue_->count("curve")) {
849         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
850         config.curveType_ = curveType;
851         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
852             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
853             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
854             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
855             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
856         }
857     }
858 
859     const WindowSceneConfig::ConfigItem& duration = item["duration"];
860     if (duration.IsInts()) {
861         auto numbers = *duration.intsValue_;
862         if (numbers.size() == 1) {
863             config.duration_ = static_cast<uint32_t>(numbers[0]);
864         }
865     }
866 }
867 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)868 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
869 {
870     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
871     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
872 
873     // config system animation
874     const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
875     systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
876         {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
877         appConfigIn.duration_);
878     const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
879     systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
880         {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
881         appConfigOut.duration_);
882 }
883 
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)884 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
885     KeyboardSceneAnimationConfig& animationOut)
886 {
887     if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
888         TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
889             "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
890             systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
891             systemConfig_.animationOut_.duration_);
892         return;
893     }
894 
895     // default animation curve params
896     constexpr char CURVETYPE[] = "interpolatingSpring";
897     constexpr float IN_CTRLX1 = 0.0f;
898     constexpr float OUT_CTRLX1 = 4.0f;
899     constexpr float CTRLY1 = 1.0f;
900     constexpr float CTRLX2 = 342.0f;
901     constexpr float CTRLY2 = 37.0f;
902     constexpr uint32_t DURATION = 150;
903     std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
904     std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
905 
906     // update system config for client
907     systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
908     systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
909 
910     // update app config for server
911     animationIn.curveType_ = CURVETYPE;
912     animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
913     animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
914     animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
915     animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
916     animationIn.duration_ = DURATION;
917 
918     animationOut.curveType_ = CURVETYPE;
919     animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
920     animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
921     animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
922     animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
923     animationOut.duration_ = DURATION;
924     TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
925 }
926 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)927 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
928 {
929     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
930     if (item.IsMap() && item.mapValue_->count("curve")) {
931         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
932         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
933         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
934             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
935             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
936             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
937             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
938         }
939     }
940     item = windowAnimationConfig["timing"]["duration"];
941     if (item.IsInts() && item.intsValue_->size() == 1) {
942         auto duration = *item.intsValue_;
943         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
944     }
945     item = windowAnimationConfig["scale"];
946     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
947         auto scales = *item.floatsValue_;
948         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
949         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
950     }
951     item = windowAnimationConfig["rotation"];
952     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
953         auto rotations = *item.floatsValue_;
954         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
955         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
956         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
957         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
958     }
959     item = windowAnimationConfig["translate"];
960     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
961         auto translates = *item.floatsValue_;
962         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
963         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
964     }
965     item = windowAnimationConfig["opacity"];
966     if (item.IsFloats() && item.floatsValue_->size() == 1) {
967         auto opacity = *item.floatsValue_;
968         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
969     }
970 }
971 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)972 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
973 {
974     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
975     auto item = configItem.GetProp("enable");
976     if (item.IsBool()) {
977         config.enabled_ = item.boolValue_;
978     }
979     item = configItem["timing"];
980     if (item.IsMap() && item.mapValue_->count("curve")) {
981         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
982     }
983     item = configItem["timing"]["duration"];
984     if (item.IsInts() && item.intsValue_->size() == 1) {
985         config.duration_ = (*item.intsValue_)[0];
986     }
987     item = configItem["opacityStart"];
988     if (item.IsFloats() && item.floatsValue_->size() == 1) {
989         config.opacityStart_ = (*item.floatsValue_)[0];
990     }
991     item = configItem["opacityEnd"];
992     if (item.IsFloats() && item.floatsValue_->size() == 1) {
993         config.opacityEnd_ = (*item.floatsValue_)[0];
994     }
995 }
996 
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)997 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
998     const WindowSceneConfig::ConfigItem& curveConfig)
999 {
1000     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1001         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1002     static std::unordered_set<std::string> paramCurveSet = {
1003         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1004 
1005     std::string curveName = "easeOut";
1006     const auto& nameItem = curveConfig.GetProp("name");
1007     if (!nameItem.IsString()) {
1008         return {curveName, {}};
1009     }
1010 
1011     std::string name = nameItem.stringValue_;
1012     std::vector<float> curveParams;
1013 
1014     if (paramCurveSet.find(name) != paramCurveSet.end()) {
1015         curveName = name;
1016         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1017         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1018             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1019                 curveParams.begin());
1020         }
1021     } else {
1022         auto iter = curveSet.find(name);
1023         if (iter != curveSet.end()) {
1024             curveName = name;
1025         }
1026     }
1027 
1028     return {curveName, curveParams};
1029 }
1030 
ConfigWindowSizeLimits()1031 void SceneSessionManager::ConfigWindowSizeLimits()
1032 {
1033     const auto& config = WindowSceneConfig::GetConfig();
1034     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1035     if (item.IsMap()) {
1036         ConfigMainWindowSizeLimits(item);
1037     }
1038 
1039     item = config["subWindowSizeLimits"];
1040     if (item.IsMap()) {
1041         ConfigSubWindowSizeLimits(item);
1042     }
1043 }
1044 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1045 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1046 {
1047     auto item = mainWindowSizeConifg["miniWidth"];
1048     if (item.IsInts()) {
1049         auto numbers = *item.intsValue_;
1050         if (numbers.size() == 1) {
1051             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1052         }
1053     }
1054 
1055     item = mainWindowSizeConifg["miniHeight"];
1056     if (item.IsInts()) {
1057         auto numbers = *item.intsValue_;
1058         if (numbers.size() == 1) {
1059             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1060         }
1061     }
1062 }
1063 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1064 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1065 {
1066     auto item = subWindowSizeConifg["miniWidth"];
1067     if (item.IsInts()) {
1068         auto numbers = *item.intsValue_;
1069         if (numbers.size() == 1) {
1070             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1071         }
1072     }
1073 
1074     item = subWindowSizeConifg["miniHeight"];
1075     if (item.IsInts()) {
1076         auto numbers = *item.intsValue_;
1077         if (numbers.size() == 1) {
1078             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1079         }
1080     }
1081 }
1082 
ConfigSnapshotScale()1083 void SceneSessionManager::ConfigSnapshotScale()
1084 {
1085     const auto& config = WindowSceneConfig::GetConfig();
1086     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1087     if (item.IsFloats()) {
1088         auto snapshotScale = *item.floatsValue_;
1089         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1090             return;
1091         }
1092         snapshotScale_ = snapshotScale[0];
1093     }
1094 }
1095 
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1096 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1097 {
1098     TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1099     WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1100     if (item.IsInts() && item.intsValue_->size() == 1) {
1101         bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1102         appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1103         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1104             appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1105     }
1106 
1107     item = statusBarConfig["immersiveStatusBarBgColor"];
1108     if (item.IsString()) {
1109         auto color = item.stringValue_;
1110         uint32_t colorValue;
1111         if (!ColorParser::Parse(color, colorValue)) {
1112             return;
1113         }
1114         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1115         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1116             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1117     }
1118 
1119     item = statusBarConfig["immersiveStatusBarContentColor"];
1120     if (item.IsString()) {
1121         auto color = item.stringValue_;
1122         uint32_t colorValue;
1123         if (!ColorParser::Parse(color, colorValue)) {
1124             return;
1125         }
1126         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1127         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1128             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1129     }
1130 }
1131 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1132 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1133 {
1134     rootSceneContextWeak_ = contextWeak;
1135 }
1136 
GetRootSceneSession()1137 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1138 {
1139     auto task = [this]() -> sptr<RootSceneSession> {
1140         if (rootSceneSession_ != nullptr) {
1141             return rootSceneSession_;
1142         }
1143         system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1144         rootSceneSession_ = new RootSceneSession();
1145         rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1146         AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1147         return rootSceneSession_;
1148     };
1149 
1150     return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1151 }
1152 
GetRootSessionAvoidSessionRect(AvoidAreaType type)1153 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1154 {
1155     sptr<RootSceneSession> rootSession = GetRootSceneSession();
1156     if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1157         return {};
1158     }
1159     DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1160     std::vector<sptr<SceneSession>> sessionVector;
1161     switch (type) {
1162         case AvoidAreaType::TYPE_SYSTEM: {
1163             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1164             break;
1165         }
1166         case AvoidAreaType::TYPE_KEYBOARD: {
1167             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1168             break;
1169         }
1170         default: {
1171             TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1172             return {};
1173         }
1174     }
1175 
1176     for (auto& session : sessionVector) {
1177         if (!session->IsVisible()) {
1178             continue;
1179         }
1180         const WSRect rect = session->GetSessionRect();
1181         TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1182         return rect;
1183     }
1184     return {};
1185 }
1186 
GetSceneSession(int32_t persistentId)1187 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1188 {
1189     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1190     auto iter = sceneSessionMap_.find(persistentId);
1191     if (iter == sceneSessionMap_.end()) {
1192         WLOGFD("Error found scene session with id: %{public}d", persistentId);
1193         return nullptr;
1194     }
1195     return iter->second;
1196 }
1197 
GetSceneSessionByName(const ComparedSessionInfo & info)1198 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const ComparedSessionInfo& info)
1199 {
1200     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1201     for (const auto &item : sceneSessionMap_) {
1202         auto sceneSession = item.second;
1203         if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1204             sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1205             sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1206             continue;
1207         }
1208         if (info.isAtomicService_) {
1209             if ((sceneSession->GetSessionInfo().moduleName_.empty() ||
1210                 sceneSession->GetSessionInfo().moduleName_ == info.moduleName_) &&
1211                 (sceneSession->GetSessionInfo().abilityName_.empty() ||
1212                 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_)) {
1213                 return sceneSession;
1214             }
1215         } else if (sceneSession->GetSessionInfo().moduleName_ == info.moduleName_ &&
1216             sceneSession->GetSessionInfo().abilityName_ == info.abilityName_) {
1217             return sceneSession;
1218         }
1219     }
1220     return nullptr;
1221 }
1222 
GetSceneSessionByType(WindowType type)1223 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1224 {
1225     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1226     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1227         if (sceneSession && sceneSession->GetWindowType() == type) {
1228             return sceneSession;
1229         }
1230     }
1231     return nullptr;
1232 }
1233 
GetSceneSessionVectorByType(WindowType type,uint64_t displayId)1234 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(
1235     WindowType type, uint64_t displayId)
1236 {
1237     if (displayId == DISPLAY_ID_INVALID) {
1238         TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1239         return {};
1240     }
1241     std::vector<sptr<SceneSession>> sceneSessionVector;
1242     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1243     for (const auto &item : sceneSessionMap_) {
1244         auto sceneSession = item.second;
1245         if (sceneSession->GetWindowType() == type &&
1246             sceneSession->GetSessionProperty() &&
1247             sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1248             sceneSessionVector.emplace_back(sceneSession);
1249         }
1250     }
1251 
1252     return sceneSessionVector;
1253 }
1254 
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1255 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1256     sptr<WindowSessionProperty> property)
1257 {
1258     if (property == nullptr) {
1259         TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1260         return WSError::WS_ERROR_NULLPTR;
1261     }
1262     if (sceneSession == nullptr) {
1263         TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1264         return WSError::WS_ERROR_NULLPTR;
1265     }
1266     auto parentPersistentId = property->GetParentPersistentId();
1267     sceneSession->SetParentPersistentId(parentPersistentId);
1268     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1269         auto parentSession = GetSceneSession(parentPersistentId);
1270         if (parentSession == nullptr) {
1271             TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1272             return WSError::WS_ERROR_NULLPTR;
1273         }
1274         parentSession->BindDialogSessionTarget(sceneSession);
1275         parentSession->BindDialogToParentSession(sceneSession);
1276         sceneSession->SetParentSession(parentSession);
1277         TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1278             sceneSession->GetPersistentId(), parentPersistentId);
1279     }
1280     return WSError::WS_OK;
1281 }
1282 
CreateSpecificSessionCallback()1283 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1284 {
1285     sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
1286     if (specificCb == nullptr) {
1287         WLOGFE("SpecificSessionCallback is nullptr");
1288         return nullptr;
1289     }
1290     specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1291         return this->RequestSceneSession(sessionInfo, property);
1292     };
1293     specificCb->onDestroy_ = [this](const int32_t persistentId) {
1294         return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1295     };
1296     specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1297         this->ClearDisplayStatusBarTemporarilyFlags();
1298     };
1299     specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1300         this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1301     };
1302     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type, uint64_t displayId) {
1303         return this->GetSceneSessionVectorByType(type, displayId);
1304     };
1305     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1306         this->UpdateAvoidArea(persistentId);
1307     };
1308     specificCb->onUpdateAvoidAreaByType_ = [this](int32_t persistentId, AvoidAreaType type) {
1309         this->UpdateAvoidAreaByType(persistentId, type);
1310     };
1311     specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1312         this->UpdateOccupiedAreaIfNeed(persistentId);
1313     };
1314     specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1315         this->NotifyWindowInfoChange(persistentId, type);
1316     };
1317     specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1318         this->NotifyMMIWindowPidChange(windowId, startMoving);
1319     };
1320     specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1321         this->NotifySessionTouchOutside(persistentId);
1322     };
1323     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1324         return this->GetAINavigationBarArea(displayId);
1325     };
1326     specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1327         this->OnOutsideDownEvent(x, y);
1328     };
1329     specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1330         return this->HandleSecureSessionShouldHide(sceneSession);
1331     };
1332     specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1333         this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1334     };
1335     specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1336         this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1337     };
1338     specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1339         this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1340     };
1341     specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1342         this->UpdateGestureBackEnabled(persistentId);
1343     };
1344     return specificCb;
1345 }
1346 
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1347 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1348 {
1349     TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1350     auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1351     if (isSkip) {
1352         if (it == skipSurfaceNodeIds_.end()) {
1353             skipSurfaceNodeIds_.push_back(surfaceNodeId);
1354         } else {
1355             return;
1356         }
1357     } else {
1358         if (it != skipSurfaceNodeIds_.end()) {
1359             skipSurfaceNodeIds_.erase(it);
1360         } else {
1361             return;
1362         }
1363     }
1364     rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1365 }
1366 
CreateKeyboardSessionCallback()1367 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1368 {
1369     sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1370         new (std::nothrow)KeyboardSession::KeyboardSessionCallback();
1371     if (keyboardCb == nullptr) {
1372         TLOGE(WmsLogTag::WMS_KEYBOARD, "KeyboardSessionCallback is nullptr");
1373         return keyboardCb;
1374     }
1375     keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1376         return this->GetSceneSession(persistentId);
1377     };
1378     keyboardCb->onGetFocusedSessionId_ = [this] {
1379         return this->GetFocusedSessionId();
1380     };
1381     keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1382 
1383     return keyboardCb;
1384 }
1385 
CheckWindowId(int32_t windowId,int32_t & pid)1386 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1387 {
1388     if (!SessionPermission::IsSystemCalling()) {
1389         TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1390         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1391     }
1392 
1393     auto task = [this, windowId, &pid]() -> WMError {
1394         pid = INVALID_PID;
1395         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1396         auto iter = sceneSessionMap_.find(windowId);
1397         if (iter == sceneSessionMap_.end()) {
1398             WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
1399             return WMError::WM_ERROR_INVALID_WINDOW;
1400         }
1401         auto sceneSession = iter->second;
1402         if (sceneSession == nullptr) {
1403             WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1404             return WMError::WM_ERROR_INVALID_WINDOW;
1405         }
1406         pid = sceneSession->GetCallingPid();
1407         WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1408         return WMError::WM_OK;
1409     };
1410     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1411 }
1412 
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1413 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1414 {
1415     if (!isKeyboardPanelEnabled_) {
1416         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1417         return;
1418     }
1419     if (keyboardSession == nullptr) {
1420         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1421         return;
1422     }
1423     auto sessionProperty = keyboardSession->GetSessionProperty();
1424     if (sessionProperty == nullptr) {
1425         TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1426         return;
1427     }
1428     DisplayId displayId = sessionProperty->GetDisplayId();
1429     const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1430     sptr<SceneSession> panelSession;
1431     if (panelVec.size() > 1) {
1432         TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1433         return;
1434     } else if (panelVec.size() == 1) {
1435         panelSession = panelVec.front();
1436         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1437     } else {
1438         SessionInfo panelInfo = {
1439             .bundleName_ = "SCBKeyboardPanel",
1440             .moduleName_ = "SCBKeyboardPanel",
1441             .abilityName_ = "SCBKeyboardPanel",
1442             .isSystem_ = true,
1443             .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1444             .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1445             .screenId_ = static_cast<uint64_t>(displayId),
1446             .isRotable_ = true,
1447         };
1448         static bool is2in1 = systemConfig_.uiType_ == UI_TYPE_PC;
1449         if (is2in1) {
1450             panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1451             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1452         } else {
1453             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1454         }
1455         panelSession = RequestSceneSession(panelInfo, nullptr);
1456         if (panelSession == nullptr) {
1457             TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1458             return;
1459         }
1460     }
1461     keyboardSession->BindKeyboardPanelSession(panelSession);
1462     panelSession->BindKeyboardSession(keyboardSession);
1463     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1464         panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1465 }
1466 
OnSCBSystemSessionBufferAvailable(WindowType type)1467 void SceneSessionManager::OnSCBSystemSessionBufferAvailable(WindowType type)
1468 {
1469     TLOGI(WmsLogTag::WMS_MULTI_USER, "In");
1470     if (type == WindowType::WINDOW_TYPE_KEYGUARD) {
1471         TLOGI(WmsLogTag::WMS_MULTI_USER, "On screen lock buffer available");
1472     }
1473 }
1474 
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1475 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1476     sptr<WindowSessionProperty> property)
1477 {
1478     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1479     sptr<SceneSession> sceneSession = nullptr;
1480     if (sessionInfo.isSystem_) {
1481         sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
1482         WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1483         if (sceneSession != nullptr &&
1484             static_cast<OHOS::Rosen::WindowType>(sessionInfo.windowType_) == WindowType::WINDOW_TYPE_KEYGUARD) {
1485             TLOGI(WmsLogTag::WMS_MULTI_USER, "Register screen lock buffer available");
1486             sceneSession->RegisterBufferAvailableCallback([this] {
1487                 this->OnSCBSystemSessionBufferAvailable(WindowType::WINDOW_TYPE_KEYGUARD);
1488             });
1489         }
1490     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1491         sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
1492         if (sceneSession != nullptr) {
1493             TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1494         }
1495     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1496         sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
1497         TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1498     } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1499         sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1500         sceneSession = new (std::nothrow) KeyboardSession(sessionInfo, specificCb, keyboardCb);
1501         CreateKeyboardPanelSession(sceneSession);
1502         TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1503     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1504         sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
1505         TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1506     } else {
1507         TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1508     }
1509     if (sceneSession != nullptr) {
1510         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1511         sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1512         sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1513             return this->GetAppForceLandscapeConfig(bundleName);
1514         });
1515         sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1516             this->UpdatePrivateStateAndNotify(persistentId);
1517         });
1518         sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1519             this->NotifyVisibleChange(persistentId);
1520         });
1521         sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
1522             return this->IsLastFrameLayoutFinished(isLayoutFinished);
1523         });
1524     }
1525     return sceneSession;
1526 }
1527 
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1528 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1529     sptr<WindowSessionProperty> property)
1530 {
1531     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1532         auto session = GetSceneSession(sessionInfo.persistentId_);
1533         if (session != nullptr) {
1534             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1535             TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1536             return session;
1537         }
1538         if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1539             TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1540                 "abilityName: %{public}s, appIndex: %{public}d",
1541                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1542                 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1543             ComparedSessionInfo compareSessionInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_,
1544                 sessionInfo.appIndex_, sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1545             auto sceneSession = GetSceneSessionByName(compareSessionInfo);
1546             bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1547                 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1548             if (isSingleStart) {
1549                 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1550                 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1551                     sessionInfo.persistentId_);
1552                 return sceneSession;
1553             }
1554         }
1555     }
1556 
1557     const char* const where = __func__;
1558     auto task = [this, sessionInfo, property, where] {
1559         TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession, appName: [%{public}s %{public}s %{public}s]"
1560             "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1561             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1562             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1563             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1564         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1565         if (sceneSession == nullptr) {
1566             TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1567             return sceneSession;
1568         }
1569         InitSceneSession(sceneSession, sessionInfo, property);
1570         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1571             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1572                 where, sceneSession->GetSessionInfo().ancoSceneState);
1573             bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1574             const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1575             if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1576                 TLOGNI(WmsLogTag::WMS_LIFE,
1577                     "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1578                     where, reusedSceneSession->GetPersistentId(),
1579                     reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1580                 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1581                 return reusedSceneSession;
1582             }
1583             if (isPreHandleSuccess) {
1584                 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1585                 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1586             }
1587         }
1588         {
1589             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1590             sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1591         }
1592         PerformRegisterInRequestSceneSession(sceneSession);
1593         TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession id: %{public}d, type: %{public}d",
1594             sceneSession->GetPersistentId(), sceneSession->GetWindowType());
1595         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1596         return sceneSession;
1597     };
1598     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1599 }
1600 
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)1601 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1602     const sptr<WindowSessionProperty>& property)
1603 {
1604     auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1605     DisplayId curDisplayId = DISPLAY_ID_INVALID;
1606     if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1607         curDisplayId = sessionInfo.screenId_;
1608     } else if (callerSession) {
1609         auto callerSessionProperty = callerSession->GetSessionProperty();
1610         if (callerSessionProperty) {
1611             curDisplayId = callerSessionProperty->GetDisplayId();
1612         }
1613     }
1614     auto sessionProperty = sceneSession->GetSessionProperty();
1615     if (sessionProperty) {
1616         sessionProperty->SetDisplayId(curDisplayId);
1617         sceneSession->SetScreenId(curDisplayId);
1618         TLOGD(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
1619             curDisplayId);
1620     }
1621     sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
1622     sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
1623     if (sessionInfo.isSystem_) {
1624         sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1625         sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1626         auto rootContext = rootSceneContextWeak_.lock();
1627         sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1628     } else {
1629         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
1630             "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
1631             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1632             sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1633     }
1634     RegisterSessionExceptionFunc(sceneSession);
1635     // Skip FillSessionInfo when atomicService free-install start.
1636     if (!IsAtomicServiceFreeInstall(sessionInfo)) {
1637         FillSessionInfo(sceneSession);
1638     }
1639     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
1640     if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
1641         sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
1642     }
1643     sceneSession->SetSystemConfig(systemConfig_);
1644     sceneSession->SetSnapshotScale(snapshotScale_);
1645     UpdateParentSessionForDialog(sceneSession, property);
1646 }
1647 
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)1648 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1649 {
1650     sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
1651     if (info == nullptr) {
1652         WLOGFE("new info failed");
1653         return;
1654     }
1655     info->action_ = action;
1656     info->abilityName_ = sessionInfo.abilityName_;
1657     info->bundleName_ = sessionInfo.bundleName_;
1658     info->toScreenId_ = sessionInfo.screenId_;
1659     info->fromScreenId_ = fromScreenId;
1660     ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1661     WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
1662         info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1663 }
1664 
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)1665 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1666 {
1667     RegisterSessionSnapshotFunc(sceneSession);
1668     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1669     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1670     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1671     RegisterGetStateFromManagerFunc(sceneSession);
1672     RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
1673     RegisterAcquireRotateAnimationConfigFunc(sceneSession);
1674 }
1675 
UpdateSceneSessionWant(const SessionInfo & sessionInfo)1676 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1677 {
1678     if (sessionInfo.persistentId_ != 0) {
1679         auto session = GetSceneSession(sessionInfo.persistentId_);
1680         if (session != nullptr && sessionInfo.want != nullptr) {
1681             TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
1682             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1683                 session->SetSessionInfoWant(sessionInfo.want);
1684                 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
1685             } else {
1686                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1687             }
1688         } else {
1689             TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
1690                 session == nullptr, sessionInfo.persistentId_);
1691         }
1692     } else {
1693         TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
1694     }
1695 }
1696 
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)1697 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
1698 {
1699     if (session != nullptr) {
1700         if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1701             FillSessionInfo(session);
1702             if (CheckCollaboratorType(session->GetCollaboratorType())) {
1703                 PreHandleCollaborator(session, persistentId);
1704             }
1705         }
1706     }
1707 }
1708 
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)1709 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
1710 {
1711     sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
1712     if (abilitySessionInfo == nullptr) {
1713         WLOGFE("abilitySessionInfo is nullptr");
1714         return nullptr;
1715     }
1716     auto sessionInfo = scnSession->GetSessionInfo();
1717     sptr<ISession> iSession(scnSession);
1718     abilitySessionInfo->sessionToken = iSession->AsObject();
1719     abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
1720         std::chrono::system_clock::now()).time_since_epoch().count());
1721     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
1722     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
1723         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
1724     abilitySessionInfo->persistentId = scnSession->GetPersistentId();
1725     abilitySessionInfo->requestCode = sessionInfo.requestCode;
1726     abilitySessionInfo->resultCode = sessionInfo.resultCode;
1727     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
1728     abilitySessionInfo->startSetting = sessionInfo.startSetting;
1729     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
1730     abilitySessionInfo->userId = currentUserId_;
1731     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
1732     abilitySessionInfo->processOptions = sessionInfo.processOptions;
1733     if (sessionInfo.want != nullptr) {
1734         abilitySessionInfo->want = *sessionInfo.want;
1735     } else {
1736         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
1737             sessionInfo.moduleName_);
1738     }
1739     int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
1740     bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
1741     if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
1742         TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
1743             appIndex, sessionInfo.appIndex_);
1744     }
1745     if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
1746         TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
1747         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
1748     }
1749     auto sessionProperty = scnSession->GetSessionProperty();
1750     if (sessionProperty) {
1751         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
1752             static_cast<int>(sessionProperty->GetDisplayId()));
1753     }
1754     if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
1755         sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
1756         abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
1757     } else {
1758         TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
1759     }
1760     return abilitySessionInfo;
1761 }
1762 
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)1763 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
1764 {
1765     auto task = [this, persistentId, &isPrepareTerminate]() {
1766         if (!isPrepareTerminateEnable_) { // not support prepareTerminate
1767             isPrepareTerminate = false;
1768             WLOGE("not support prepareTerminate, Id:%{public}d", persistentId);
1769             return WSError::WS_OK;
1770         }
1771         auto scnSession = GetSceneSession(persistentId);
1772         if (scnSession == nullptr) {
1773             WLOGFE("PrepareTerminate scnSession is nullptr, Id:%{public}d", persistentId);
1774             isPrepareTerminate = false;
1775             return WSError::WS_ERROR_NULLPTR;
1776         }
1777         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1778         if (scnSessionInfo == nullptr) {
1779             WLOGFE("PrepareTerminate scnSessionInfo is nullptr, Id:%{public}d", persistentId);
1780             isPrepareTerminate = false;
1781             return WSError::WS_ERROR_NULLPTR;
1782         }
1783         TLOGI(WmsLogTag::WMS_MAIN, "PrepareTerminateAbilityBySCB Id:%{public}d", persistentId);
1784         auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
1785             PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
1786         TLOGI(WmsLogTag::WMS_MAIN, "PrepareTerminateAbilityBySCB isPrepareTerminate:%{public}d errorCode:%{public}d",
1787             isPrepareTerminate, errorCode);
1788         return WSError::WS_OK;
1789     };
1790 
1791     taskScheduler_->PostSyncTask(task, "PrepareTerminate:PID:" + std::to_string(persistentId));
1792     return WSError::WS_OK;
1793 }
1794 
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)1795 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
1796 {
1797     wptr<SceneSession> weakSceneSession(sceneSession);
1798     auto task = [this, weakSceneSession, isNewActive]() {
1799         sptr<SceneSession> scnSession = weakSceneSession.promote();
1800         if (scnSession == nullptr) {
1801             TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
1802             return WSError::WS_ERROR_NULLPTR;
1803         }
1804         auto persistentId = scnSession->GetPersistentId();
1805         if (!Session::IsScbCoreEnabled()) {
1806             scnSession->SetForegroundInteractiveStatus(true);
1807         }
1808         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
1809         TLOGI(WmsLogTag::WMS_MAIN, "Request active id:%{public}d system:%{public}u isNewActive:%{public}d",
1810             persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_), isNewActive);
1811         if (!GetSceneSession(persistentId)) {
1812             TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
1813             return WSError::WS_ERROR_INVALID_SESSION;
1814         }
1815         auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
1816         if (ret == WSError::WS_OK) {
1817             scnSession->SetExitSplitOnBackground(false);
1818         }
1819         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
1820         return ret;
1821     };
1822     std::string taskName = "RequestSceneSessionActivation:PID:" +
1823         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
1824     taskScheduler_->PostAsyncTask(task, taskName);
1825     return WSError::WS_OK;
1826 }
1827 
IsKeyboardForeground()1828 bool SceneSessionManager::IsKeyboardForeground()
1829 {
1830     bool isKeyboardForeground = false;
1831     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1832     for (const auto &item : sceneSessionMap_) {
1833         auto sceneSession = item.second;
1834         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1835             isKeyboardForeground = sceneSession->IsSessionForeground();
1836             break;
1837         }
1838     }
1839 
1840     return isKeyboardForeground;
1841 }
1842 
RequestInputMethodCloseKeyboard(const int32_t persistentId)1843 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
1844 {
1845     auto sceneSession = GetSceneSession(persistentId);
1846     if (sceneSession == nullptr) {
1847         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
1848         return;
1849     }
1850     // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
1851     if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
1852         !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
1853         TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
1854             persistentId, sceneSession->GetSessionState());
1855         sceneSession->RequestHideKeyboard(true);
1856     }
1857 }
1858 
StartUIAbilityBySCB(sptr<SceneSession> & scnSession)1859 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
1860 {
1861     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1862     if (abilitySessionInfo == nullptr) {
1863         return ERR_NULL_OBJECT;
1864     }
1865     return StartUIAbilityBySCB(abilitySessionInfo);
1866 }
1867 
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)1868 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
1869 {
1870     bool isColdStart = false;
1871     return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
1872 }
1873 
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession> & scnSession,bool visibility)1874 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
1875 {
1876     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1877     if (abilitySessionInfo == nullptr) {
1878         return ERR_NULL_OBJECT;
1879     }
1880     return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
1881 }
1882 
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive)1883 WSError SceneSessionManager::RequestSceneSessionActivationInner(
1884     sptr<SceneSession>& scnSession, bool isNewActive)
1885 {
1886     auto persistentId = scnSession->GetPersistentId();
1887     RequestInputMethodCloseKeyboard(persistentId);
1888     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1889         scnSession->SetIsStarting(true);
1890         scnSession->SetStartingBeforeVisible(true);
1891     }
1892     if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
1893         if (Session::IsScbCoreEnabled()) {
1894             if (scnSession->IsVisibleForeground()) {
1895                 RequestSessionFocusImmediately(persistentId);
1896             } else {
1897                 PostProcessFocusState state = { true, true, FocusChangeReason::SCB_START_APP };
1898                 scnSession->SetPostProcessFocusState(state);
1899             }
1900         } else {
1901             RequestSessionFocusImmediately(persistentId);
1902         }
1903     }
1904     if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1905         FillSessionInfo(scnSession);
1906         if (!PreHandleCollaborator(scnSession, persistentId)) {
1907             TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
1908                 persistentId, scnSession->GetSessionInfo().ancoSceneState);
1909             scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
1910             return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
1911         }
1912     }
1913     auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1914     if (!scnSessionInfo) {
1915         TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
1916         return WSError::WS_ERROR_NULLPTR;
1917     }
1918     scnSession->NotifyActivation();
1919     scnSessionInfo->isNewWant = isNewActive;
1920     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1921         scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
1922         scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
1923     }
1924     TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
1925         "module: %{public}s, uri: %{public}s, appIndex: %{public}d.", persistentId,
1926         scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
1927         scnSessionInfo->want.GetElement().GetBundleName().c_str(),
1928         scnSessionInfo->want.GetElement().GetModuleName().c_str(),
1929         scnSessionInfo->want.GetElement().GetURI().c_str(),
1930         scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0));
1931     int32_t errCode = ERR_OK;
1932     bool isColdStart = false;
1933     if (systemConfig_.backgroundswitch == false) {
1934         TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
1935             static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1936         errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1937     } else {
1938         TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
1939             isNewActive, scnSession->GetSessionState());
1940         if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
1941             scnSession->GetSessionState() == SessionState::STATE_END) {
1942             TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
1943                 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1944             errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1945         } else {
1946             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
1947             scnSession->NotifySessionForeground(1, true);
1948         }
1949     }
1950     auto sessionInfo = scnSession->GetSessionInfo();
1951     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1952         WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
1953     }
1954     NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
1955 
1956     if (errCode != ERR_OK) {
1957         TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
1958         scnSession->NotifySessionExceptionInner(scnSessionInfo, true, false, true);
1959         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
1960             startUIAbilityErrorFunc_(
1961                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
1962         }
1963     }
1964     if (isColdStart) {
1965         TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
1966             scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
1967         scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
1968         scnSession->ResetSessionConnectState();
1969     }
1970     return WSError::WS_OK;
1971 }
1972 
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)1973 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
1974     sptr<AAFwk::SessionInfo>& scnSessionInfo)
1975 {
1976     if (scnSession == nullptr || scnSessionInfo == nullptr) {
1977         return;
1978     }
1979     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1980         NotifyLoadAbility(scnSession->GetCollaboratorType(),
1981             scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
1982         NotifyUpdateSessionInfo(scnSession);
1983         NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
1984         scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
1985     }
1986 }
1987 
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)1988 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
1989     const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
1990 {
1991     wptr<SceneSession> weakSceneSession(sceneSession);
1992     auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
1993         auto scnSession = weakSceneSession.promote();
1994         if (scnSession == nullptr) {
1995             TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
1996             return WSError::WS_ERROR_NULLPTR;
1997         }
1998         auto persistentId = scnSession->GetPersistentId();
1999         TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2000             "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2001             persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2002         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2003         scnSession->SetActive(false);
2004 
2005         if (isToDesktop) {
2006             auto info = scnSession->GetSessionInfo();
2007             info.callerToken_ = nullptr;
2008             info.callingTokenId_ = 0;
2009             scnSession->SetSessionInfo(info);
2010         }
2011 
2012         scnSession->BackgroundTask(isSaveSnapshot);
2013         if (!GetSceneSession(persistentId)) {
2014             TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2015             return WSError::WS_ERROR_INVALID_SESSION;
2016         }
2017         if (persistentId == brightnessSessionId_) {
2018             UpdateBrightness(focusedSessionId_);
2019         }
2020         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2021         if (!scnSessionInfo) {
2022             TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2023             return WSError::WS_ERROR_NULLPTR;
2024         }
2025         bool isPcAppInpad = false;
2026         auto property = scnSession->GetSessionProperty();
2027         if (property) {
2028             isPcAppInpad = property->GetIsPcAppInPad();
2029         }
2030         if (systemConfig_.backgroundswitch || isPcAppInpad) {
2031             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2032             scnSession->NotifySessionBackground(1, true, true);
2033         } else {
2034             TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2035                 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2036             if (!isDelegator) {
2037                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2038             } else {
2039                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2040             }
2041         }
2042 
2043         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2044             auto sessionInfo = scnSession->GetSessionInfo();
2045             WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2046         }
2047         return WSError::WS_OK;
2048     };
2049     std::string taskName = "RequestSceneSessionBackground:PID:" +
2050         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2051     taskScheduler_->PostAsyncTask(task, taskName);
2052     return WSError::WS_OK;
2053 }
2054 
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2055 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2056 {
2057     wptr<SceneSession> weakSceneSession(sceneSession);
2058     auto task = [this, weakSceneSession, interactive]() {
2059         auto scnSession = weakSceneSession.promote();
2060         if (scnSession == nullptr) {
2061             WLOGFE("session is nullptr");
2062             return;
2063         }
2064         auto persistentId = scnSession->GetPersistentId();
2065         WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2066         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2067         if (!GetSceneSession(persistentId)) {
2068             WLOGFE("session is invalid with %{public}d", persistentId);
2069             return;
2070         }
2071         scnSession->NotifyForegroundInteractiveStatus(interactive);
2072     };
2073 
2074     taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2075 }
2076 
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)2077 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2078 {
2079     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2080     if (scnSession == nullptr) {
2081         TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2082         return WSError::WS_ERROR_NULLPTR;
2083     }
2084     if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2085         TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2086         auto dialogVec = scnSession->GetDialogVector();
2087         for (auto dialog : dialogVec) {
2088             if (dialog == nullptr) {
2089                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2090                 continue;
2091             }
2092             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2093             if (sceneSession == nullptr) {
2094                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2095                 return WSError::WS_ERROR_INVALID_SESSION;
2096             }
2097             WindowDestroyNotifyVisibility(sceneSession);
2098             dialog->NotifyDestroy();
2099             dialog->Disconnect();
2100 
2101             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2102             if (dialogSceneSession != nullptr) {
2103                 dialogSceneSession->ClearSpecificSessionCbMap();
2104             }
2105             {
2106                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2107                 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2108                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2109                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2110             }
2111         }
2112         scnSession->ClearDialogVector();
2113         return WSError::WS_OK;
2114     }
2115     return WSError::WS_ERROR_INVALID_SESSION;
2116 }
2117 
DestroySubSession(const sptr<SceneSession> & sceneSession)2118 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2119 {
2120     if (sceneSession == nullptr) {
2121         WLOGFW("sceneSession is nullptr");
2122         return;
2123     }
2124     for (const auto& elem : sceneSession->GetSubSession()) {
2125         if (elem != nullptr) {
2126             const auto& persistentId = elem->GetPersistentId();
2127             TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2128             DestroyAndDisconnectSpecificSessionInner(persistentId);
2129         }
2130     }
2131 }
2132 
DestroyToastSession(const sptr<SceneSession> & sceneSession)2133 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2134 {
2135     if (sceneSession == nullptr) {
2136         TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2137         return;
2138     }
2139     for (const auto& elem : sceneSession->GetToastSession()) {
2140         if (elem != nullptr) {
2141             const auto& persistentId = elem->GetPersistentId();
2142             TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2143             DestroyAndDisconnectSpecificSessionInner(persistentId);
2144         }
2145     }
2146 }
2147 
EraseSceneSessionMapById(int32_t persistentId)2148 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2149 {
2150     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2151     EraseSceneSessionAndMarkDirtyLocked(persistentId);
2152     systemTopSceneSessionMap_.erase(persistentId);
2153     nonSystemFloatSceneSessionMap_.erase(persistentId);
2154 }
2155 
2156 /**
2157  * if visible session is erased, mark dirty
2158  * lock-free
2159  */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2160 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2161 {
2162     // get scene session lock-free
2163     auto iter = sceneSessionMap_.find(persistentId);
2164     if (iter == sceneSessionMap_.end()) {
2165         TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2166         return;
2167     }
2168     sptr<SceneSession> sceneSession = iter->second;
2169     if (sceneSession != nullptr && sceneSession->IsVisible()) {
2170         sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2171     }
2172     sceneSessionMap_.erase(persistentId);
2173 }
2174 
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean)2175 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2176     bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2177 {
2178     auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2179         needRemoveSession, isSaveSnapshot, isForceClean]() {
2180         auto scnSession = weakSceneSession.promote();
2181         if (scnSession == nullptr) {
2182             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2183             return WSError::WS_ERROR_NULLPTR;
2184         }
2185         auto persistentId = scnSession->GetPersistentId();
2186         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2187         RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2188         lastUpdatedAvoidArea_.erase(persistentId);
2189         DestroyDialogWithMainWindow(scnSession);
2190         DestroyToastSession(scnSession);
2191         DestroySubSession(scnSession); // destroy sub session by destruction
2192         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2193             " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2194         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2195         WindowDestroyNotifyVisibility(scnSession);
2196         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2197         scnSession->DisconnectTask(false, isSaveSnapshot);
2198         if (!GetSceneSession(persistentId)) {
2199             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2200             return WSError::WS_ERROR_INVALID_SESSION;
2201         }
2202         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2203         if (!scnSessionInfo) {
2204             return WSError::WS_ERROR_NULLPTR;
2205         }
2206         scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2207         if (scnSessionInfo->resultCode == -1) {
2208             OHOS::AAFwk::Want want;
2209             scnSessionInfo->want = want;
2210         }
2211         return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2212     };
2213     std::string taskName = "RequestSceneSessionDestruction:PID:" +
2214         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2215     taskScheduler_->PostAsyncTask(task, taskName);
2216     return WSError::WS_OK;
2217 }
2218 
ResetWant(sptr<SceneSession> & sceneSession)2219 void SceneSessionManager::ResetWant(sptr<SceneSession>& sceneSession)
2220 {
2221     auto& sessionInfo = sceneSession->GetSessionInfo();
2222     if (sessionInfo.want != nullptr) {
2223         const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2224         const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2225         const auto& keySessionId = sessionInfo.want->GetStringParam(KEY_SESSION_ID);
2226         auto want = std::make_shared<AAFwk::Want>();
2227         if (want != nullptr) {
2228             AppExecFwk::ElementName element;
2229             element.SetBundleName(bundleName);
2230             element.SetAbilityName(abilityName);
2231             want->SetElement(element);
2232             want->SetBundle(bundleName);
2233             if (!keySessionId.empty()) {
2234                 want->SetParam(KEY_SESSION_ID, keySessionId);
2235             }
2236             sceneSession->SetSessionInfoWant(want);
2237         }
2238     }
2239 }
2240 
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession,const bool isForceClean)2241 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& scnSession,
2242     sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2243 {
2244     auto persistentId = scnSession->GetPersistentId();
2245     TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}u",
2246         persistentId,
2247         static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2248     if (isForceClean) {
2249         AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2250     } else {
2251         AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2252     }
2253     scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2254     if (needRemoveSession) {
2255         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2256             NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2257         }
2258         EraseSceneSessionMapById(persistentId);
2259     } else {
2260         // if terminate, reset want. so start from recent, start a new one.
2261         TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2262         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2263             scnSession->SetSessionInfoWant(nullptr);
2264         }
2265         ResetWant(scnSession);
2266         scnSession->ResetSessionInfoResultCode();
2267     }
2268     if (listenerController_ != nullptr) {
2269         NotifySessionForCallback(scnSession, needRemoveSession);
2270     }
2271     scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2272     return WSError::WS_OK;
2273 }
2274 
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)2275 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2276     const sptr<SceneSession>& sceneSession)
2277 {
2278     if (sceneSession == nullptr || sessionStage == nullptr) {
2279         TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2280         return;
2281     }
2282 
2283     auto remoteObject = sessionStage->AsObject();
2284     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2285     if (windowDeath_ == nullptr) {
2286         TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2287         return;
2288     }
2289     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2290         TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2291         return;
2292     }
2293     WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2294 }
2295 
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)2296 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2297 {
2298     auto task = [this, remoteObject]() {
2299         auto iter = remoteObjectMap_.find(remoteObject);
2300         if (iter == remoteObjectMap_.end()) {
2301             WLOGFE("Invalid remoteObject");
2302             return;
2303         }
2304         WLOGFD("Remote died, id: %{public}d", iter->second);
2305         auto session = GetSceneSession(iter->second);
2306         if (session == nullptr) {
2307             WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2308             return;
2309         }
2310         DestroyAndDisconnectSpecificSessionInner(iter->second);
2311     };
2312     taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2313 }
2314 
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)2315 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2316     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2317     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2318     SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2319 {
2320     if (property == nullptr) {
2321         WLOGFE("property is nullptr");
2322         return WSError::WS_ERROR_NULLPTR;
2323     }
2324 
2325     if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2326         WLOGFE("create system window or modal subwindow permission denied!");
2327         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2328     }
2329 
2330     bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2331                         property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2332     bool isSystemCalling = SessionPermission::IsSystemCalling();
2333     if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2334         auto parentSession = GetSceneSession(property->GetParentPersistentId());
2335         if (parentSession) {
2336             shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2337         }
2338     }
2339     if (shouldBlock) {
2340         TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2341         return WSError::WS_ERROR_INVALID_OPERATION;
2342     }
2343 
2344     if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2345         property->GetExtensionFlag() == true && SessionPermission::IsStartedByUIExtension()) {
2346         auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2347         if (extensionParentSession == nullptr) {
2348             WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2349             return WSError::WS_ERROR_NULLPTR;
2350         }
2351         SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2352         AAFwk::UIExtensionHostInfo hostInfo;
2353         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2354         if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2355             WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2356                 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2357                 hostInfo.elementName_.GetBundleName().c_str());
2358             return WSError::WS_ERROR_INVALID_WINDOW;
2359         }
2360     }
2361 
2362     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2363     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2364         WLOGFE("The alarm window has been deprecated!");
2365         return WSError::WS_ERROR_INVALID_WINDOW;
2366     }
2367 
2368     if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2369         WLOGFE("pip window is not enable to create.");
2370         return WSError::WS_DO_NOTHING;
2371     }
2372     TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2373         property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2374 
2375     // Get pid and uid before posting task.
2376     auto pid = IPCSkeleton::GetCallingRealPid();
2377     auto uid = IPCSkeleton::GetCallingUid();
2378     auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2379                     &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2380         if (property == nullptr) {
2381             WLOGFE("[WMSSub][WMSSystem] property is nullptr");
2382             return WSError::WS_ERROR_NULLPTR;
2383         }
2384         const auto& type = property->GetWindowType();
2385         // create specific session
2386         SessionInfo info;
2387         info.windowType_ = static_cast<uint32_t>(type);
2388         info.bundleName_ = property->GetSessionInfo().bundleName_;
2389         info.abilityName_ = property->GetSessionInfo().abilityName_;
2390         info.moduleName_ = property->GetSessionInfo().moduleName_;
2391 
2392         ClosePipWindowIfExist(type);
2393         sptr<SceneSession> newSession = RequestSceneSession(info, property);
2394         if (newSession == nullptr) {
2395             TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2396             return WSError::WS_ERROR_NULLPTR;
2397         }
2398         auto errCode = newSession->ConnectInner(
2399             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2400         newSession->SetIsSystemSpecificSession(isSystemCalling);
2401         systemConfig = systemConfig_;
2402         if (property) {
2403             persistentId = property->GetPersistentId();
2404         }
2405 
2406         NotifyCreateSpecificSession(newSession, property, type);
2407         session = newSession;
2408         AddClientDeathRecipient(sessionStage, newSession);
2409         TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2410             "parentId: %{public}d, type: %{public}d",
2411             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2412         return errCode;
2413     };
2414 
2415     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2416 }
2417 
ClosePipWindowIfExist(WindowType type)2418 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2419 {
2420     if (type != WindowType::WINDOW_TYPE_PIP) {
2421         return;
2422     }
2423     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2424     for (const auto& iter: sceneSessionMap_) {
2425         auto& session = iter.second;
2426         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2427             session->NotifyCloseExistPipWindow();
2428             break;
2429         }
2430     }
2431 }
2432 
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)2433 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2434 {
2435     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2436     for (const auto& iter: sceneSessionMap_) {
2437         auto& session = iter.second;
2438         if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2439             pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2440             session->IsSessionForeground()) {
2441             if (startPiPFailedFunc_) {
2442                 startPiPFailedFunc_();
2443             }
2444             TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2445             return false;
2446         }
2447     }
2448     return true;
2449 }
2450 
isEnablePiPCreate(const sptr<WindowSessionProperty> & property)2451 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2452 {
2453     if (isScreenLocked_) {
2454         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2455         return false;
2456     }
2457     Rect pipRect = property->GetRequestRect();
2458     if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2459         TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2460         return false;
2461     }
2462     if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2463         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2464         return false;
2465     }
2466     auto parentSession = GetSceneSession(property->GetParentPersistentId());
2467     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2468         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2469         return false;
2470     }
2471     return true;
2472 }
2473 
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)2474 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2475 {
2476     WindowType type = property->GetWindowType();
2477     if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
2478         return true;
2479     }
2480 
2481     if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
2482         TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
2483         return false;
2484     }
2485 
2486     if (!SessionPermission::IsSystemCalling()) {
2487         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
2488         return false;
2489     }
2490 
2491     return true;
2492 }
2493 
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)2494 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
2495 {
2496     WindowType type = property->GetWindowType();
2497     if (WindowHelper::IsUIExtensionWindow(type)) {
2498         // UIExtension window disallowed.
2499         return false;
2500     }
2501     if (!WindowHelper::IsSystemWindow(type)) {
2502         // type is not system
2503         return true;
2504     }
2505     if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)
2506         && SessionPermission::IsStartedByInputMethod()) {
2507         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
2508         WLOGFD("check create permission success, input method app create input method window.");
2509         return true;
2510     }
2511     if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
2512         // some system types could be created by normal app
2513         return true;
2514     }
2515     if (type == WindowType::WINDOW_TYPE_FLOAT &&
2516         SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2517         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
2518         if (systemConfig_.supportTypeFloatWindow_) {
2519             WLOGFD("check create float window permission success on 2in1 device.");
2520             return true;
2521         }
2522     }
2523     if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
2524         int32_t parentId = property->GetParentPersistentId();
2525         auto parentSession = GetSceneSession(parentId);
2526         if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2527             SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2528             TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
2529             return true;
2530         } else {
2531             TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
2532         }
2533     }
2534     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
2535         TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
2536         return true;
2537     }
2538     WLOGFE("check system window permission failed.");
2539     return false;
2540 }
2541 
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)2542 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
2543 {
2544     SessionInfo sessionInfo;
2545     if (property == nullptr) {
2546         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2547         return sessionInfo;
2548     }
2549     sessionInfo = property->GetSessionInfo();
2550     sessionInfo.persistentId_ = property->GetPersistentId();
2551     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
2552     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
2553     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
2554     sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
2555                                     ? SessionState::STATE_ACTIVE
2556                                     : SessionState::STATE_BACKGROUND;
2557     sessionInfo.isPersistentRecover_ = true;
2558     TLOGI(WmsLogTag::WMS_RECOVER,
2559         "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
2560         "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
2561         "windowState=%{public}u",
2562         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2563         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_);
2564     return sessionInfo;
2565 }
2566 
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)2567 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
2568 {
2569     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
2570            "%{public}d", alivePersistentIds.size(), currentUserId_);
2571     alivePersistentIds_ = alivePersistentIds;
2572 }
2573 
IsNeedRecover(const int32_t persistentId)2574 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
2575 {
2576     auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
2577     if (it == alivePersistentIds_.end()) {
2578         TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
2579         return false;
2580     }
2581     return true;
2582 }
2583 
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)2584 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
2585     bool isSpecificSession)
2586 {
2587     if (property == nullptr) {
2588         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2589         return WSError::WS_ERROR_NULLPTR;
2590     }
2591     if (!CheckSystemWindowPermission(property)) {
2592         TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
2593         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2594     }
2595     if (isSpecificSession) {
2596         if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
2597             return WSError::WS_ERROR_INVALID_PARAM;
2598         }
2599     } else {
2600         if (!IsNeedRecover(property->GetPersistentId())) {
2601             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2602             return WSError::WS_ERROR_INVALID_PARAM;
2603         }
2604     }
2605     return WSError::WS_OK;
2606 }
2607 
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)2608 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2609     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2610     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
2611 {
2612     auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
2613     if (propCheckRet != WSError::WS_OK) {
2614         return propCheckRet;
2615     }
2616     auto pid = IPCSkeleton::GetCallingRealPid();
2617     auto uid = IPCSkeleton::GetCallingUid();
2618     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
2619         if (recoveringFinished_) {
2620             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2621             return WSError::WS_ERROR_INVALID_OPERATION;
2622         }
2623         // recover specific session
2624         SessionInfo info = RecoverSessionInfo(property);
2625         TLOGI(WmsLogTag::WMS_RECOVER, "callingWindowId = %{public}" PRIu32, property->GetCallingSessionId());
2626         ClosePipWindowIfExist(property->GetWindowType());
2627         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
2628         if (sceneSession == nullptr) {
2629             TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
2630             return WSError::WS_ERROR_NULLPTR;
2631         }
2632 
2633         auto persistentId = sceneSession->GetPersistentId();
2634         if (persistentId != info.persistentId_) {
2635             TLOGE(WmsLogTag::WMS_RECOVER,
2636                 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
2637                 info.persistentId_, persistentId, property->GetParentPersistentId());
2638             failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
2639             EraseSceneSessionMapById(persistentId);
2640             return WSError::WS_ERROR_INVALID_SESSION;
2641         }
2642 
2643         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2644         if (errCode != WSError::WS_OK) {
2645             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
2646             EraseSceneSessionMapById(persistentId);
2647             return errCode;
2648         }
2649         NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
2650         CacheSubSessionForRecovering(sceneSession, property);
2651         NotifySessionUnfocusedToClient(persistentId);
2652         AddClientDeathRecipient(sessionStage, sceneSession);
2653         session = sceneSession;
2654         return errCode;
2655     };
2656     return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
2657 }
2658 
NotifyRecoveringFinished()2659 void SceneSessionManager::NotifyRecoveringFinished()
2660 {
2661     taskScheduler_->PostAsyncTask([this]() {
2662             TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
2663             recoveringFinished_ = true;
2664             recoverSubSessionCacheMap_.clear();
2665         }, "NotifyRecoveringFinished");
2666 }
2667 
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)2668 void SceneSessionManager::CacheSubSessionForRecovering(
2669     sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
2670 {
2671     if (recoveringFinished_) {
2672         TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
2673         return;
2674     }
2675 
2676     if (sceneSession == nullptr || property == nullptr) {
2677         TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
2678         return;
2679     }
2680 
2681     auto windowType = property->GetWindowType();
2682     if (!SessionHelper::IsSubWindow(windowType)) {
2683         return;
2684     }
2685 
2686     auto persistentId = property->GetParentPersistentId();
2687     if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
2688         return;
2689     }
2690 
2691     TLOGI(WmsLogTag::WMS_RECOVER,
2692         "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
2693         sceneSession->GetPersistentId(), persistentId);
2694 
2695     if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
2696         recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
2697     } else {
2698         recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
2699     }
2700 }
2701 
RecoverCachedSubSession(int32_t persistentId)2702 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
2703 {
2704     auto iter = recoverSubSessionCacheMap_.find(persistentId);
2705     if (iter == recoverSubSessionCacheMap_.end()) {
2706         return;
2707     }
2708 
2709     TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
2710     for (auto& sceneSession : iter->second) {
2711         NotifyCreateSubSession(persistentId, sceneSession);
2712     }
2713     recoverSubSessionCacheMap_.erase(iter);
2714 }
2715 
NotifySessionUnfocusedToClient(int32_t persistentId)2716 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
2717 {
2718     if (listenerController_ != nullptr) {
2719         TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
2720         listenerController_->NotifySessionUnfocused(persistentId);
2721     }
2722 }
2723 
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)2724 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
2725     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2726     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
2727 {
2728     auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
2729     if (propCheckRet != WSError::WS_OK) {
2730         return propCheckRet;
2731     }
2732     auto pid = IPCSkeleton::GetCallingRealPid();
2733     auto uid = IPCSkeleton::GetCallingUid();
2734     auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
2735         if (recoveringFinished_) {
2736             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2737             return WSError::WS_ERROR_INVALID_OPERATION;
2738         }
2739         if (recoverSceneSessionFunc_ == nullptr) {
2740             TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
2741             return WSError::WS_ERROR_NULLPTR;
2742         }
2743         SessionInfo sessionInfo = RecoverSessionInfo(property);
2744         sptr<SceneSession> sceneSession = nullptr;
2745         if (SessionHelper::IsMainWindow(property->GetWindowType())) {
2746             sceneSession = RequestSceneSession(sessionInfo, nullptr);
2747         } else {
2748             sceneSession = RequestSceneSession(sessionInfo, property);
2749         }
2750         if (sceneSession == nullptr) {
2751             TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
2752             return WSError::WS_ERROR_NULLPTR;
2753         }
2754         int32_t persistentId = sceneSession->GetPersistentId();
2755         if (persistentId != sessionInfo.persistentId_) {
2756             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
2757                 sessionInfo.persistentId_, persistentId);
2758             EraseSceneSessionMapById(persistentId);
2759             return WSError::WS_ERROR_INVALID_SESSION;
2760         }
2761         auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2762         if (ret != WSError::WS_OK) {
2763             TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
2764             EraseSceneSessionMapById(sessionInfo.persistentId_);
2765             return ret;
2766         }
2767         sceneSession->SetRecovered(true);
2768         recoverSceneSessionFunc_(sceneSession, sessionInfo);
2769         NotifySessionUnfocusedToClient(persistentId);
2770         session = sceneSession;
2771         return WSError::WS_OK;
2772     };
2773     return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
2774 }
2775 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)2776 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
2777 {
2778     TLOGI(WmsLogTag::WMS_RECOVER, "called");
2779     recoverSceneSessionFunc_ = func;
2780 }
2781 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)2782 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
2783 {
2784     createSystemSessionFunc_ = func;
2785 }
2786 
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)2787 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
2788 {
2789     createKeyboardSessionFunc_ = func;
2790 }
2791 
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)2792 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
2793 {
2794     startPiPFailedFunc_ = std::move(func);
2795 }
2796 
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)2797 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
2798     const NotifyCreateSubSessionFunc& func)
2799 {
2800     TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
2801     auto task = [this, persistentId, func]() {
2802         createSubSessionFuncMap_[persistentId] = func;
2803         RecoverCachedSubSession(persistentId);
2804         return WMError::WM_OK;
2805     };
2806     taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
2807 }
2808 
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)2809 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
2810     sptr<WindowSessionProperty> property, const WindowType& type)
2811 {
2812     if (newSession == nullptr) {
2813         WLOGFE("newSession is nullptr");
2814         return;
2815     }
2816     if (property == nullptr) {
2817         WLOGFE("property is nullptr");
2818         return;
2819     }
2820     if (SessionHelper::IsSystemWindow(type)) {
2821         if (type == WindowType::WINDOW_TYPE_FLOAT) {
2822             auto parentSession = GetSceneSession(property->GetParentPersistentId());
2823             if (parentSession != nullptr) {
2824                 newSession->SetParentSession(parentSession);
2825             }
2826         }
2827         if (type == WindowType::WINDOW_TYPE_TOAST) {
2828             NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
2829         }
2830         if (type != WindowType::WINDOW_TYPE_DIALOG) {
2831             if (WindowHelper::IsSystemSubWindow(type)) {
2832                 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2833             } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
2834                 && createKeyboardSessionFunc_) {
2835                 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
2836             } else if (createSystemSessionFunc_) {
2837                 createSystemSessionFunc_(newSession);
2838             }
2839             TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
2840                 newSession->GetPersistentId(), type);
2841         } else {
2842             TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, \
2843                 type:%{public}d", newSession->GetPersistentId(), type);
2844             return;
2845         }
2846     } else if (SessionHelper::IsSubWindow(type)) {
2847         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2848         TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
2849             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
2850     } else {
2851         TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
2852             newSession->GetPersistentId(), type);
2853     }
2854 }
2855 
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)2856 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
2857 {
2858     if (session == nullptr) {
2859         TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
2860         return;
2861     }
2862     auto iter = createSubSessionFuncMap_.find(persistentId);
2863     if (iter == createSubSessionFuncMap_.end()) {
2864         TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
2865         return;
2866     }
2867 
2868     sptr<SceneSession> parentSession = nullptr;
2869     if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
2870         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2871         parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
2872     } else {
2873         parentSession = GetSceneSession(persistentId);
2874     }
2875     if (parentSession == nullptr) {
2876         TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
2877             persistentId, session->GetPersistentId());
2878         return;
2879     }
2880     parentSession->AddSubSession(session);
2881     session->SetParentSession(parentSession);
2882     if (iter->second) {
2883         iter->second(session);
2884     }
2885     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
2886         persistentId, session->GetPersistentId());
2887 }
2888 
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)2889 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
2890     const std::map<int32_t, sptr<SceneSession>>& sessionMap)
2891 {
2892     if (persistentId == INVALID_SESSION_ID) {
2893         TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
2894         return nullptr;
2895     }
2896     auto iter = sessionMap.find(persistentId);
2897     if (iter == sessionMap.end()) {
2898         WLOGFD("Error found scene session with id: %{public}d", persistentId);
2899         return nullptr;
2900     }
2901     sptr<SceneSession> parentSession = iter->second;
2902     if (parentSession == nullptr) {
2903         TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
2904         return nullptr;
2905     }
2906     bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
2907         parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
2908     if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
2909         TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
2910         return parentSession;
2911     }
2912     return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
2913 }
2914 
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)2915 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
2916 {
2917     if (session == nullptr) {
2918         TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
2919         return;
2920     }
2921 
2922     auto parentSession = GetSceneSession(persistentId);
2923     if (parentSession == nullptr) {
2924         TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
2925             persistentId, session->GetPersistentId());
2926         return;
2927     }
2928     parentSession->AddToastSession(session);
2929     session->SetParentSession(parentSession);
2930     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
2931         persistentId, session->GetPersistentId());
2932 }
2933 
UnregisterCreateSubSessionListener(int32_t persistentId)2934 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
2935 {
2936     TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
2937     auto task = [this, persistentId]() {
2938         auto iter = createSubSessionFuncMap_.find(persistentId);
2939         if (iter != createSubSessionFuncMap_.end()) {
2940             createSubSessionFuncMap_.erase(persistentId);
2941         } else {
2942             TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
2943         }
2944         return WMError::WM_OK;
2945     };
2946     taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
2947 }
2948 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)2949 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
2950 {
2951     WLOGFD("SetStatusBarEnabledChangeListener");
2952     if (!func) {
2953         WLOGFD("set func is null");
2954     }
2955     statusBarEnabledChangeFunc_ = func;
2956 }
2957 
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)2958 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
2959     const ProcessGestureNavigationEnabledChangeFunc& func)
2960 {
2961     WLOGFD("SetGestureNavigationEnabledChangeListener");
2962     if (!func) {
2963         WLOGFD("set func is null");
2964     }
2965     gestureNavigationEnabledChangeFunc_ = func;
2966 }
2967 
OnOutsideDownEvent(int32_t x,int32_t y)2968 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
2969 {
2970     TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
2971     if (outsideDownEventFunc_) {
2972         outsideDownEventFunc_(x, y);
2973     }
2974 }
2975 
NotifySessionTouchOutside(int32_t persistentId)2976 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
2977 {
2978     auto task = [this, persistentId]() {
2979         int32_t callingSessionId = INVALID_SESSION_ID;
2980         auto sceneSession = GetSceneSession(persistentId);
2981         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2982             callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
2983             TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
2984                 persistentId, callingSessionId);
2985         }
2986         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2987         for (const auto &item : sceneSessionMap_) {
2988             sceneSession = item.second;
2989             if (sceneSession == nullptr) {
2990                 continue;
2991             }
2992             if (!(sceneSession->IsVisible() ||
2993                 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
2994                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
2995                 continue;
2996             }
2997             auto sessionId = sceneSession->GetPersistentId();
2998             if ((!sceneSession->CheckOutTouchOutsideRegister()) &&
2999                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3000                 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3001                 continue;
3002             }
3003             if (sessionId == callingSessionId || sessionId == persistentId) {
3004                 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3005                 continue;
3006             }
3007             sceneSession->NotifyTouchOutside();
3008         }
3009     };
3010 
3011     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3012     return;
3013 }
3014 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)3015 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3016 {
3017     WLOGFD("SetOutsideDownEventListener");
3018     outsideDownEventFunc_ = func;
3019 }
3020 
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)3021 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
3022 {
3023     for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
3024         if (iter->second != persistentId) {
3025             continue;
3026         }
3027         if (windowDeath_ == nullptr) {
3028             TLOGE(WmsLogTag::WMS_LIFE, "death recipient is null");
3029         } else {
3030             if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
3031                 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
3032             }
3033         }
3034         remoteObjectMap_.erase(iter);
3035         break;
3036     }
3037 }
3038 
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3039 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3040 {
3041     auto sceneSession = GetSceneSession(persistentId);
3042     if (sceneSession == nullptr) {
3043         return WSError::WS_ERROR_NULLPTR;
3044     }
3045     auto ret = sceneSession->UpdateActiveStatus(false);
3046     WindowDestroyNotifyVisibility(sceneSession);
3047     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
3048         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3049         if (parentSession == nullptr) {
3050             TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3051         } else {
3052             parentSession->RemoveDialogToParentSession(sceneSession);
3053         }
3054     }
3055     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_TOAST) {
3056         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3057         if (parentSession != nullptr) {
3058             TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3059             parentSession->RemoveToastSession(persistentId);
3060         } else {
3061             TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3062         }
3063     }
3064     ret = sceneSession->Disconnect();
3065     sceneSession->ClearSpecificSessionCbMap();
3066     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3067         DestroySubSession(sceneSession);
3068         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3069         if (parentSession != nullptr) {
3070             TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3071             parentSession->RemoveSubSession(sceneSession->GetPersistentId());
3072         } else {
3073             TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3074         }
3075     }
3076     {
3077         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3078         EraseSceneSessionAndMarkDirtyLocked(persistentId);
3079         systemTopSceneSessionMap_.erase(persistentId);
3080         nonSystemFloatSceneSessionMap_.erase(persistentId);
3081         UnregisterCreateSubSessionListener(persistentId);
3082     }
3083     ClearSpecificSessionRemoteObjectMap(persistentId);
3084     TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3085     return ret;
3086 }
3087 
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3088 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3089 {
3090     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3091     auto task = [this, persistentId, callingPid]() {
3092         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3093         auto sceneSession = GetSceneSession(persistentId);
3094         if (sceneSession == nullptr) {
3095             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3096             return WSError::WS_ERROR_NULLPTR;
3097         }
3098 
3099         if (callingPid != sceneSession->GetCallingPid()) {
3100             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3101             return WSError::WS_ERROR_INVALID_PERMISSION;
3102         }
3103         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3104     };
3105 
3106     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3107 }
3108 
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)3109 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3110     const sptr<IRemoteObject>& callback)
3111 {
3112     if (callback == nullptr) {
3113         return WSError::WS_ERROR_NULLPTR;
3114     }
3115     const auto callingPid = IPCSkeleton::GetCallingRealPid();
3116     auto task = [this, persistentId, callingPid, callback]() {
3117         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3118         auto sceneSession = GetSceneSession(persistentId);
3119         if (sceneSession == nullptr) {
3120             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3121             return WSError::WS_ERROR_NULLPTR;
3122         }
3123 
3124         if (callingPid != sceneSession->GetCallingPid()) {
3125             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3126             return WSError::WS_ERROR_INVALID_PERMISSION;
3127         }
3128         sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3129         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3130     };
3131 
3132     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3133 }
3134 
GetWindowSceneConfig() const3135 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3136 {
3137     return appWindowSceneConfig_;
3138 }
3139 
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)3140 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3141 {
3142     auto task = [this, config]() {
3143         TLOGI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3144         rotateAnimationConfig_.duration_ = config.duration_;
3145     };
3146     taskScheduler_->PostAsyncTask(task, "UpdateRotateAnimationConfig");
3147 }
3148 
ProcessBackEvent()3149 WSError SceneSessionManager::ProcessBackEvent()
3150 {
3151     auto task = [this]() {
3152         auto session = GetSceneSession(focusedSessionId_);
3153         if (!session) {
3154             TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId_);
3155             return WSError::WS_ERROR_INVALID_SESSION;
3156         }
3157         TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
3158             focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3159         if (needBlockNotifyFocusStatusUntilForeground_) {
3160             TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
3161             if (session->GetSessionInfo().abilityInfo != nullptr &&
3162                 session->GetSessionInfo().abilityInfo->unclearableMission) {
3163                 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3164                 return WSError::WS_OK;
3165             }
3166             session->RequestSessionBack(true);
3167             return WSError::WS_OK;
3168         }
3169         if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3170             rootSceneProcessBackEventFunc_();
3171         } else {
3172             session->ProcessBackEvent();
3173         }
3174         return WSError::WS_OK;
3175     };
3176 
3177     taskScheduler_->PostAsyncTask(task, __func__);
3178     return WSError::WS_OK;
3179 }
3180 
InitUserInfo(int32_t userId,std::string & fileDir)3181 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3182 {
3183     if (userId == DEFAULT_USERID || fileDir.empty()) {
3184         TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3185         return WSError::WS_DO_NOTHING;
3186     }
3187     TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3188     auto task = [this, userId, &fileDir]() {
3189         if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3190             TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3191         }
3192         if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3193             TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3194         }
3195         currentUserId_ = userId;
3196         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3197         RegisterSecSurfaceInfoListener();
3198         return WSError::WS_OK;
3199     };
3200     return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3201 }
3202 
NotifySwitchingUser(const bool isUserActive)3203 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3204 {
3205     auto task = [this, isUserActive]() {
3206         TLOGI(WmsLogTag::WMS_MULTI_USER, "Notify switching user. IsUserActive=%{public}u, currentUserId=%{public}d",
3207             isUserActive, currentUserId_);
3208         isUserBackground_ = !isUserActive;
3209         SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3210         if (isUserActive) { // switch to current user
3211             SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3212             // notify screenSessionManager to recover current user
3213             ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3214             FlushWindowInfoToMMI(true);
3215             NotifyAllAccessibilityInfo();
3216             rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3217         } else { // switch to another user
3218             SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3219             rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3220         }
3221         return WSError::WS_OK;
3222     };
3223     taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3224 }
3225 
GetBundleManager()3226 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3227 {
3228     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3229     if (systemAbilityMgr == nullptr) {
3230         WLOGFE("Failed to get SystemAbilityManager.");
3231         return nullptr;
3232     }
3233 
3234     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3235     if (bmsObj == nullptr) {
3236         WLOGFE("Failed to get BundleManagerService.");
3237         return nullptr;
3238     }
3239 
3240     return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3241 }
3242 
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)3243 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3244     const AppExecFwk::AbilityInfo& abilityInfo)
3245 {
3246     auto context = rootSceneContextWeak_.lock();
3247     if (!context) {
3248         WLOGFE("context is nullptr.");
3249         return nullptr;
3250     }
3251     auto resourceMgr = context->GetResourceManager();
3252     if (!resourceMgr) {
3253         WLOGFE("resourceMgr is nullptr.");
3254         return nullptr;
3255     }
3256     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3257     if (!resConfig) {
3258         WLOGFE("resConfig is nullptr.");
3259         return nullptr;
3260     }
3261     resourceMgr->GetResConfig(*resConfig);
3262     resourceMgr = Global::Resource::CreateResourceManager(
3263         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3264     if (!resourceMgr) {
3265         WLOGFE("resourceMgr is nullptr.");
3266         return nullptr;
3267     }
3268     resourceMgr->UpdateResConfig(*resConfig);
3269 
3270     std::string loadPath;
3271     if (!abilityInfo.hapPath.empty()) { // zipped hap
3272         loadPath = abilityInfo.hapPath;
3273     } else {
3274         loadPath = abilityInfo.resourcePath;
3275     }
3276 
3277     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3278         WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3279     }
3280     return resourceMgr;
3281 }
3282 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)3283 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3284     std::string& path, uint32_t& bgColor)
3285 {
3286     auto resourceMgr = GetResourceManager(abilityInfo);
3287     if (!resourceMgr) {
3288         WLOGFE("resourceMgr is nullptr.");
3289         return false;
3290     }
3291 
3292     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3293         WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3294         return false;
3295     }
3296 
3297     if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3298         WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3299         return false;
3300     }
3301 
3302     if (!abilityInfo.hapPath.empty()) { // zipped hap
3303         auto pos = path.find_last_of('.');
3304         if (pos == std::string::npos) {
3305             WLOGFE("Format error, path %{private}s.", path.c_str());
3306             return false;
3307         }
3308         path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3309     }
3310     return true;
3311 }
3312 
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3313 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3314 {
3315     if (!bundleMgr_) {
3316         WLOGFE("bundleMgr_ is nullptr.");
3317         return;
3318     }
3319     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3320     if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3321         WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3322         return;
3323     }
3324     AAFwk::Want want;
3325     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3326     AppExecFwk::AbilityInfo abilityInfo;
3327     if (!bundleMgr_->QueryAbilityInfo(
3328         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3329         WLOGFE("Get ability info from BMS failed!");
3330         return;
3331     }
3332 
3333     if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3334         CacheStartingWindowInfo(abilityInfo, path, bgColor);
3335     }
3336     WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3337         abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3338 }
3339 
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3340 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3341     const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3342 {
3343     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3344     std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3345     auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3346     if (iter == startingWindowMap_.end()) {
3347         return false;
3348     }
3349     auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3350     const auto& infoMap = iter->second;
3351     auto infoMapIter = infoMap.find(key);
3352     if (infoMapIter == infoMap.end()) {
3353         return false;
3354     }
3355     path = infoMapIter->second.startingWindowIconPath_;
3356     bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3357     return true;
3358 }
3359 
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)3360 void SceneSessionManager::CacheStartingWindowInfo(
3361     const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3362 {
3363     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3364     auto key = abilityInfo.moduleName + abilityInfo.name;
3365     StartingWindowInfo info = {
3366         .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3367         .startingWindowIconId_ = abilityInfo.startWindowIconId,
3368         .startingWindowBackgroundColor_ = bgColor,
3369         .startingWindowIconPath_ = path,
3370     };
3371     std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3372     auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3373     if (iter != startingWindowMap_.end()) {
3374         auto& infoMap = iter->second;
3375         infoMap.emplace(key, info);
3376         return;
3377     }
3378     if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3379         startingWindowMap_.erase(startingWindowMap_.begin());
3380     }
3381     std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3382     startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3383 }
3384 
OnBundleUpdated(const std::string & bundleName,int userId)3385 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3386 {
3387     taskScheduler_->PostAsyncTask([this, bundleName]() {
3388         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3389         auto iter = startingWindowMap_.find(bundleName);
3390         if (iter != startingWindowMap_.end()) {
3391             startingWindowMap_.erase(iter);
3392         }
3393     },
3394         "OnBundleUpdated");
3395 }
3396 
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3397 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3398 {
3399     taskScheduler_->PostAsyncTask([this]() {
3400         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3401         startingWindowMap_.clear();
3402     },
3403         "OnConfigurationUpdated");
3404 }
3405 
FillSessionInfo(sptr<SceneSession> & sceneSession)3406 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3407 {
3408     auto sessionInfo = sceneSession->GetSessionInfo();
3409     if (sessionInfo.bundleName_.empty()) {
3410         WLOGFE("bundleName_ is empty");
3411         return;
3412     }
3413     if (sessionInfo.isSystem_) {
3414         WLOGFD("is system scene!");
3415         return;
3416     }
3417     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3418         sessionInfo.moduleName_);
3419     if (abilityInfo == nullptr) {
3420         WLOGFE("abilityInfo is nullptr!");
3421         return;
3422     }
3423     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3424     sceneSession->SetSessionInfoTime(GetCurrentTime());
3425     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3426         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3427     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3428         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3429     }
3430     TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3431         "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3432         abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3433         abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3434 }
3435 
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)3436 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3437     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3438 {
3439     if (!bundleMgr_) {
3440         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3441         return nullptr;
3442     }
3443     AAFwk::Want want;
3444     want.SetElementName("", bundleName, abilityName, moduleName);
3445     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3446     if (abilityInfo == nullptr) {
3447         WLOGFE("abilityInfo is nullptr!");
3448         return nullptr;
3449     }
3450     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3451         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3452         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3453     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
3454     if (!ret) {
3455         WLOGFE("Get ability info from BMS failed!");
3456         return nullptr;
3457     }
3458     return abilityInfo;
3459 }
3460 
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)3461 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
3462     uint32_t& topWinId, uint32_t& zOrder)
3463 {
3464     const auto& subVec = session->GetSubSession();
3465     for (const auto& subSession : subVec) {
3466         if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
3467             TLOGW(WmsLogTag::WMS_SUB,
3468                 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
3469             continue;
3470         }
3471         if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3472              subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
3473             subSession->GetZOrder() > zOrder) {
3474             topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
3475             zOrder = subSession->GetZOrder();
3476             TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
3477                 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
3478         }
3479         if (subSession->GetSubSession().size() > 0) {
3480             GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
3481         }
3482     }
3483 }
3484 
3485 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)3486 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
3487 {
3488     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3489     auto task = [this, mainWinId, &topWinId, callingPid]() {
3490         const auto& mainSession = GetSceneSession(mainWinId);
3491         if (mainSession == nullptr) {
3492             return WMError::WM_ERROR_INVALID_WINDOW;
3493         }
3494 
3495         if (callingPid != mainSession->GetCallingPid()) {
3496             WLOGFE("Permission denied, not destroy by the same process");
3497             return WMError::WM_ERROR_INVALID_PERMISSION;
3498         }
3499         uint32_t zOrder = mainSession->GetZOrder();
3500         topWinId = mainWinId;
3501         GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
3502         TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
3503             "zOrder: %{public}d", mainWinId, topWinId, zOrder);
3504         return WMError::WM_OK;
3505     };
3506 
3507     if (!Session::IsScbCoreEnabled()) {
3508         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3509     }
3510     bool postNow = false;
3511     auto mainSession = GetSceneSession(mainWinId);
3512     if (mainSession != nullptr) {
3513         postNow = !(mainSession->GetUIStateDirty());
3514     }
3515     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
3516     if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
3517         taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
3518         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3519     }
3520     TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
3521     {
3522         std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
3523         if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
3524             std::cv_status::timeout) {
3525             TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
3526         }
3527     }
3528     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3529 }
3530 
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)3531 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
3532     int32_t windowId, int32_t& mainWindowId)
3533 {
3534     auto iter = sceneSessionMap.find(windowId);
3535     if (iter == sceneSessionMap.end()) {
3536         TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
3537         return WMError::WM_ERROR_NULLPTR;
3538     }
3539     sptr<SceneSession> sceneSession = iter->second;
3540     if (sceneSession == nullptr) {
3541         TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
3542         return WMError::WM_ERROR_NULLPTR;
3543     }
3544     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3545         mainWindowId = sceneSession->GetPersistentId();
3546         return WMError::WM_OK;
3547     }
3548     if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3549         WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
3550         return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
3551     }
3552     // not sub window, dialog, return invalid id
3553     mainWindowId = INVALID_SESSION_ID;
3554     return WMError::WM_OK;
3555 }
3556 
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)3557 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
3558 {
3559     if (windowId == INVALID_SESSION_ID) {
3560         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3561         return WMError::WM_ERROR_INVALID_PARAM;
3562     }
3563     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3564     return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
3565 }
3566 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3567 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
3568     const sptr<SceneSession>& sceneSession)
3569 {
3570     auto systemBarProperties = property->GetSystemBarProperty();
3571     for (auto iter : systemBarProperties) {
3572         if (iter.first == type) {
3573             sceneSession->SetSystemBarProperty(iter.first, iter.second);
3574             TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
3575                 static_cast<int32_t>(iter.first), iter.second.enable_);
3576         }
3577     }
3578     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3579 }
3580 
3581 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3582 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
3583     const sptr<SceneSession>& sceneSession)
3584 {
3585     if (!SessionPermission::IsSystemCalling()) {
3586         TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
3587         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3588     }
3589 
3590     sceneSession->SetTopmost(property->IsTopmost());
3591     return WMError::WM_OK;
3592 }
3593 
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3594 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3595     const sptr<SceneSession>& sceneSession)
3596 {
3597     auto propertyOld = sceneSession->GetSessionProperty();
3598     if (propertyOld == nullptr) {
3599         TLOGI(WmsLogTag::DEFAULT, "session property null");
3600         return;
3601     }
3602 
3603     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
3604     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
3605     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
3606         TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
3607         return;
3608     }
3609 
3610     if (IsSessionVisibleForeground(sceneSession)) {
3611         if (hideNonSystemFloatingWindowsOld) {
3612             UpdateForceHideState(sceneSession, propertyOld, false);
3613         } else {
3614             UpdateForceHideState(sceneSession, property, true);
3615         }
3616     }
3617 }
3618 
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)3619 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
3620     const sptr<WindowSessionProperty>& property, bool add)
3621 {
3622     if (property == nullptr) {
3623         WLOGFD("property is nullptr");
3624         return;
3625     }
3626     auto persistentId = sceneSession->GetPersistentId();
3627     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
3628     bool notifyAll = false;
3629     if (add) {
3630         if (property->GetHideNonSystemFloatingWindows()) {
3631             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
3632             notifyAll = !forceHideFloatOld;
3633         } else if (property->IsFloatingWindowAppType()) {
3634             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
3635             if (forceHideFloatOld) {
3636                 sceneSession->NotifyForceHideChange(true);
3637             }
3638         }
3639     } else {
3640         if (property->GetHideNonSystemFloatingWindows()) {
3641             systemTopSceneSessionMap_.erase(persistentId);
3642             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
3643         } else if (property->IsFloatingWindowAppType()) {
3644             nonSystemFloatSceneSessionMap_.erase(persistentId);
3645             if (property->GetForceHide()) {
3646                 sceneSession->NotifyForceHideChange(false);
3647             }
3648         }
3649     }
3650     if (notifyAll) {
3651         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
3652         for (const auto &item : nonSystemFloatSceneSessionMap_) {
3653             auto forceHideSceneSession = item.second;
3654             auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
3655             if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
3656                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
3657             }
3658         }
3659     }
3660 }
3661 
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)3662 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
3663 {
3664 #ifdef POWER_MANAGER_ENABLE
3665     auto task = [this, sceneSession]() {
3666         if (sceneSession == nullptr) {
3667             WLOGFE("session is invalid");
3668             return;
3669         }
3670         WLOGFD("Win: %{public}s, is turn on%{public}d",
3671             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
3672         std::string identity = IPCSkeleton::ResetCallingIdentity();
3673         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
3674             WLOGI("turn screen on");
3675             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
3676         }
3677         // set ipc identity to raw
3678         IPCSkeleton::SetCallingIdentity(identity);
3679     };
3680     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
3681 
3682 #else
3683     WLOGFD("Can not found the sub system of PowerMgr");
3684 #endif
3685 }
3686 
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)3687 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
3688 {
3689 #ifdef POWER_MANAGER_ENABLE
3690     wptr<SceneSession> weakSceneSession(sceneSession);
3691     auto task = [this, weakSceneSession, requireLock]() {
3692         auto scnSession = weakSceneSession.promote();
3693         if (scnSession == nullptr) {
3694             WLOGFE("session is invalid");
3695             return;
3696         }
3697         if (requireLock && scnSession->keepScreenLock_ == nullptr) {
3698             // reset ipc identity
3699             std::string identity = IPCSkeleton::ResetCallingIdentity();
3700             scnSession->keepScreenLock_ =
3701                 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
3702                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
3703             // set ipc identity to raw
3704             IPCSkeleton::SetCallingIdentity(identity);
3705         }
3706         if (scnSession->keepScreenLock_ == nullptr) {
3707             return;
3708         }
3709         bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession);
3710         TLOGNI(WmsLogTag::DEFAULT, "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d]",
3711             scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
3712             scnSession->IsVisible(), requireLock, shouldLock);
3713         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
3714         ErrCode res;
3715         std::string identity = IPCSkeleton::ResetCallingIdentity();
3716         if (shouldLock) {
3717             res = scnSession->keepScreenLock_->Lock();
3718         } else {
3719             res = scnSession->keepScreenLock_->UnLock();
3720         }
3721         // set ipc identity to raw
3722         IPCSkeleton::SetCallingIdentity(identity);
3723         if (res != ERR_OK) {
3724             WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
3725                 requireLock, res);
3726         }
3727     };
3728     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
3729 #else
3730     WLOGFD("Can not found the sub system of PowerMgr");
3731 #endif
3732 }
3733 
NotifyVisibleChange(int32_t persistentId)3734 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
3735 {
3736     auto sceneSession = GetSceneSession(persistentId);
3737     if (sceneSession == nullptr) {
3738         return false;
3739     }
3740     HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
3741     ProcessWindowModeType();
3742     return true;
3743 }
3744 
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)3745 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
3746 {
3747 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
3748     if (GetDisplayBrightness() != brightness && eventHandler_ != nullptr &&
3749         GetFocusedSessionId() == sceneSession->GetPersistentId()) {
3750         bool setBrightnessRet = false;
3751         if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3752             auto task = []() {
3753                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3754             };
3755             setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
3756             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3757         } else {
3758             auto task = [brightness]() {
3759                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3760                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3761             };
3762             setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
3763             SetDisplayBrightness(brightness);
3764         }
3765         if (!setBrightnessRet) {
3766             WLOGFE("Report post listener callback task failed. the task name is SetBrightness");
3767         }
3768     }
3769 #else
3770     WLOGFD("Can not found the sub system of DisplayPowerMgr");
3771 #endif
3772     brightnessSessionId_ = sceneSession->GetPersistentId();
3773     return WSError::WS_OK;
3774 }
3775 
UpdateBrightness(int32_t persistentId)3776 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
3777 {
3778     auto sceneSession = GetSceneSession(persistentId);
3779     if (sceneSession == nullptr) {
3780         WLOGFE("session is invalid");
3781         return WSError::WS_ERROR_NULLPTR;
3782     }
3783     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
3784             sceneSession->GetSessionInfo().isSystem_)) {
3785         WLOGW("only app main window can set brightness");
3786         return WSError::WS_DO_NOTHING;
3787     }
3788     auto brightness = sceneSession->GetBrightness();
3789     WLOGFI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
3790     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3791         if (GetDisplayBrightness() != brightness) {
3792             WLOGI("adjust brightness with default value");
3793             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3794             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3795         }
3796         brightnessSessionId_ = INVALID_WINDOW_ID;
3797     } else {
3798         if (GetDisplayBrightness() != brightness) {
3799             WLOGI("adjust brightness with value");
3800             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3801                 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3802             SetDisplayBrightness(brightness);
3803         }
3804         brightnessSessionId_ = sceneSession->GetPersistentId();
3805     }
3806     return WSError::WS_OK;
3807 }
3808 
GetCurrentUserId() const3809 int32_t SceneSessionManager::GetCurrentUserId() const
3810 {
3811     return currentUserId_;
3812 }
3813 
SetDisplayBrightness(float brightness)3814 void SceneSessionManager::SetDisplayBrightness(float brightness)
3815 {
3816     displayBrightness_ = brightness;
3817 }
3818 
GetDisplayBrightness() const3819 float SceneSessionManager::GetDisplayBrightness() const
3820 {
3821     return displayBrightness_;
3822 }
3823 
SetGestureNavigaionEnabled(bool enable)3824 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
3825 {
3826     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3827         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
3828         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3829     }
3830     std::string callerBundleName = SessionPermission::GetCallingBundleName();
3831     TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
3832     auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
3833         SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
3834         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
3835             WLOGFE("callback func is null");
3836             return WMError::WM_OK;
3837         }
3838         if (gestureNavigationEnabledChangeFunc_) {
3839             gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
3840         }
3841         if (statusBarEnabledChangeFunc_) {
3842             statusBarEnabledChangeFunc_(enable, bundleName);
3843         }
3844         return WMError::WM_OK;
3845     };
3846     return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
3847 }
3848 
SetFocusedSessionId(int32_t persistentId)3849 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
3850 {
3851     if (focusedSessionId_ == persistentId) {
3852         WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
3853         return WSError::WS_DO_NOTHING;
3854     }
3855     lastFocusedSessionId_ = focusedSessionId_;
3856     focusedSessionId_ = persistentId;
3857     return WSError::WS_OK;
3858 }
3859 
GetFocusedSessionId() const3860 int32_t SceneSessionManager::GetFocusedSessionId() const
3861 {
3862     return focusedSessionId_;
3863 }
3864 
GetFocusWindowInfo(FocusChangeInfo & focusInfo)3865 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
3866 {
3867     if (!SessionPermission::IsSACalling()) {
3868         WLOGFE("GetFocusWindowInfo permission denied!");
3869         return;
3870     }
3871     auto sceneSession = GetSceneSession(focusedSessionId_);
3872     if (sceneSession) {
3873         WLOGFD("Get focus session info success");
3874         focusInfo.windowId_ = sceneSession->GetWindowId();
3875         focusInfo.displayId_ = static_cast<DisplayId>(0);
3876         focusInfo.pid_ = sceneSession->GetCallingPid();
3877         focusInfo.uid_ = sceneSession->GetCallingUid();
3878         focusInfo.windowType_ = sceneSession->GetWindowType();
3879         focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
3880     }
3881     return;
3882 }
3883 
IsValidDigitString(const std::string & windowIdStr)3884 static bool IsValidDigitString(const std::string& windowIdStr)
3885 {
3886     if (windowIdStr.empty()) {
3887         return false;
3888     }
3889     for (char ch : windowIdStr) {
3890         if ((ch >= '0' && ch <= '9')) {
3891             continue;
3892         }
3893         WLOGFE("invalid window id");
3894         return false;
3895     }
3896     return true;
3897 }
3898 
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)3899 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
3900 {
3901     if (sceneSession == nullptr) {
3902         WLOGFE("session is nullptr");
3903         return;
3904     }
3905     NotifySessionExceptionFunc sessionExceptionFunc = [this](
3906         const SessionInfo& info, bool needRemoveSession = false, bool startFail = false) {
3907         auto task = [this, info]() {
3908             auto scnSession = GetSceneSession(info.persistentId_);
3909             if (scnSession == nullptr) {
3910                 TLOGW(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, Not found session, id: %{public}d",
3911                     info.persistentId_);
3912                 return;
3913             }
3914             if (listenerController_ == nullptr) {
3915                 TLOGW(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, listenerController_ is nullptr");
3916                 return;
3917             }
3918             if (scnSession->GetSessionInfo().isSystem_) {
3919                 TLOGW(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, id: %{public}d is system",
3920                     scnSession->GetPersistentId());
3921                 return;
3922             }
3923             TLOGI(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, errorCode: %{public}d, id: %{public}d",
3924                 info.errorCode, info.persistentId_);
3925             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
3926                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
3927                 TLOGD(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
3928                     "or foreground timeout, id: %{public}d", info.persistentId_);
3929                 listenerController_->NotifySessionClosed(info.persistentId_);
3930             }
3931         };
3932         taskScheduler_->PostVoidSyncTask(task, "sessionException");
3933     };
3934     sceneSession->SetSessionExceptionListener(sessionExceptionFunc, false);
3935     TLOGD(WmsLogTag::WMS_LIFE, "RegisterSessionExceptionFunc success, id: %{public}d", sceneSession->GetPersistentId());
3936 }
3937 
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)3938 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
3939 {
3940     if (sceneSession == nullptr) {
3941         WLOGFE("session is nullptr");
3942         return;
3943     }
3944     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
3945         auto sceneSession = GetSceneSession(persistentId);
3946         if (sceneSession == nullptr) {
3947             WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
3948             return;
3949         }
3950         if (sceneSession->GetSessionInfo().isSystem_) {
3951             WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
3952             return;
3953         }
3954         auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
3955         if (abilityInfoPtr == nullptr) {
3956             WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
3957             return;
3958         }
3959         if (listenerController_ == nullptr) {
3960             WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
3961             return;
3962         }
3963         if (!abilityInfoPtr->excludeFromMissions) {
3964             listenerController_->NotifySessionSnapshotChanged(persistentId);
3965         }
3966     };
3967     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
3968     WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
3969 }
3970 
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)3971 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
3972 {
3973     if (sceneSession == nullptr) {
3974         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
3975         return;
3976     }
3977     AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
3978         config.duration_ = rotateAnimationConfig_.duration_;
3979     };
3980     sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
3981     TLOGD(WmsLogTag::DEFAULT, "Register acquire Rotate Animation config success, id: %{public}d",
3982         sceneSession->GetPersistentId());
3983 }
3984 
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)3985 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
3986 {
3987     if (scnSession == nullptr) {
3988         WLOGFW("NotifySessionForCallback, scnSession is nullptr");
3989         return;
3990     }
3991     if (scnSession->GetSessionInfo().isSystem_) {
3992         WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
3993         return;
3994     }
3995     WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
3996            static_cast<uint32_t>(needRemoveSession));
3997     if (scnSession->GetSessionInfo().appIndex_ != 0) {
3998         WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
3999                scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
4000         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4001         return;
4002     }
4003     if (needRemoveSession) {
4004         WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
4005         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4006         return;
4007     }
4008     if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
4009         WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
4010     } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4011                (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4012         WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4013             scnSession->GetPersistentId());
4014         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4015         return;
4016     }
4017     WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
4018     listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
4019 }
4020 
NotifyWindowInfoChangeFromSession(int32_t persistentId)4021 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4022 {
4023     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4024     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4025     if (sceneSession == nullptr) {
4026         WLOGFE("sceneSession nullptr");
4027         return;
4028     }
4029 
4030     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4031 }
4032 
IsSessionVisible(const sptr<SceneSession> & session)4033 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4034 {
4035     if (session == nullptr) {
4036         return false;
4037     }
4038     if (Session::IsScbCoreEnabled()) {
4039         return session->IsVisible();
4040     }
4041     const auto& state = session->GetSessionState();
4042     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4043         const auto& parentSceneSession = session->GetParentSession();
4044         if (parentSceneSession == nullptr) {
4045             WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
4046             return false;
4047         }
4048         const auto& parentState = parentSceneSession->GetSessionState();
4049         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4050             if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
4051                 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
4052                 return false;
4053             }
4054             WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4055             return true;
4056         }
4057         WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4058         return false;
4059     }
4060 
4061     if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
4062         WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
4063         return true;
4064     }
4065     WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
4066     return false;
4067 }
4068 
IsSessionVisibleForeground(const sptr<SceneSession> & session)4069 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4070 {
4071     if (session == nullptr) {
4072         return false;
4073     }
4074     if (Session::IsScbCoreEnabled()) {
4075         return session->IsVisibleForeground();
4076     }
4077     return IsSessionVisible(session);
4078 }
4079 
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)4080 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4081 {
4082     if (session == nullptr) {
4083         return;
4084     }
4085     int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4086     WSRect rect = session->GetSessionRect();
4087     std::string sName;
4088     if (session->GetSessionInfo().isSystem_) {
4089         sName = session->GetSessionInfo().abilityName_;
4090     } else {
4091         sName = session->GetWindowName();
4092     }
4093     uint32_t flag = 0;
4094     uint64_t displayId = INVALID_SCREEN_ID;
4095     auto sessionProperty = session->GetSessionProperty();
4096     if (sessionProperty) {
4097         flag = sessionProperty->GetWindowFlags();
4098         displayId = sessionProperty->GetDisplayId();
4099     }
4100     uint32_t orientation = 0;
4101     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4102         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4103     // std::setw is used to set the output width and different width values are set to keep the format aligned.
4104     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4105         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4106         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4107         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4108         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4109         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4110         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4111         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4112         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4113         << "[ "
4114         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4115         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4116         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4117         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4118         << "]"
4119         << " [ "
4120         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4121         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4122         << "]"
4123         << " [ "
4124         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4125         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4126         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4127         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4128         << "]"
4129         << std::endl;
4130 }
4131 
GetAllSessionDumpInfo(std::string & dumpInfo)4132 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4133 {
4134     int32_t screenGroupId = 0;
4135     std::ostringstream oss;
4136     oss << "-------------------------------------ScreenGroup " << screenGroupId
4137         << "-------------------------------------" << std::endl;
4138     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
4139         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]"
4140         << std::endl;
4141 
4142     std::vector<sptr<SceneSession>> allSession;
4143     std::vector<sptr<SceneSession>> backgroundSession;
4144     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4145     {
4146         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4147         sceneSessionMapCopy = sceneSessionMap_;
4148     }
4149     for (const auto& elem : sceneSessionMapCopy) {
4150         auto curSession = elem.second;
4151         if (curSession == nullptr || (!curSession->GetSessionInfo().isSystem_ && (curSession->GetSessionState() <
4152             SessionState::STATE_FOREGROUND || curSession->GetSessionState() > SessionState::STATE_BACKGROUND))) {
4153             WLOGFW("Session is nullptr or session state is invalid, id: %{public}d, state: %{public}u",
4154                 curSession->GetPersistentId(), curSession->GetSessionState());
4155             continue;
4156         }
4157         if (IsSessionVisibleForeground(curSession)) {
4158             allSession.push_back(curSession);
4159         } else {
4160             backgroundSession.push_back(curSession);
4161         }
4162     }
4163     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4164     uint32_t count = 0;
4165     for (const auto& session : allSession) {
4166         if (session == nullptr) {
4167             continue;
4168         }
4169         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4170             oss << "---------------------------------------------------------------------------------------"
4171                 << std::endl;
4172         }
4173         DumpSessionInfo(session, oss);
4174         count++;
4175     }
4176     oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4177     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4178     dumpInfo.append(oss.str());
4179     return WSError::WS_OK;
4180 }
4181 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)4182 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4183 {
4184     dumpRootSceneFunc_ = func;
4185 }
4186 
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)4187 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4188     const std::vector<std::string>& params, std::string& dumpInfo)
4189 {
4190     std::vector<std::string> resetParams;
4191     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4192     if (resetParams.empty()) {
4193         WLOGI("do not dump ui info");
4194         return;
4195     }
4196 
4197     if (!session->GetSessionInfo().isSystem_) {
4198         WLOGFI("Dump normal session, not system");
4199         dumpInfoFuture_.ResetLock({});
4200         session->DumpSessionElementInfo(resetParams);
4201         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4202         for (auto& info: infos) {
4203             dumpInfo.append(info).append("\n");
4204         }
4205     } else {
4206         WLOGFI("Dump system session");
4207         std::vector<std::string> infos;
4208         dumpRootSceneFunc_(resetParams, infos);
4209         for (auto& info: infos) {
4210             dumpInfo.append(info).append("\n");
4211         }
4212     }
4213 }
4214 
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)4215 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4216     const std::string& strId)
4217 {
4218     uint64_t persistentId = std::stoull(strId);
4219     auto session = GetSceneSession(persistentId);
4220     if (session == nullptr) {
4221         return WSError::WS_ERROR_INVALID_PARAM;
4222     }
4223     auto sessionProperty = session->GetSessionProperty();
4224     if (sessionProperty == nullptr) {
4225         return WSError::WS_ERROR_INVALID_PARAM;
4226     }
4227 
4228     WSRect rect = session->GetSessionRect();
4229     std::string isVisible = session->IsVisible() ? "true" : "false";
4230     std::string focusable = session->GetFocusable() ? "true" : "false";
4231     std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4232     bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4233     std::string isPrivacyMode = privacyMode ? "true" : "false";
4234     bool isFirstFrameAvailable = true;
4235     std::ostringstream oss;
4236     oss << "WindowName: " << session->GetWindowName()  << std::endl;
4237     oss << "DisplayId: " << 0 << std::endl;
4238     oss << "WinId: " << session->GetPersistentId() << std::endl;
4239     oss << "Pid: " << session->GetCallingPid() << std::endl;
4240     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4241     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4242     oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4243     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4244     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4245     oss << "IsVisible: " << isVisible << std::endl;
4246     oss << "Focusable: "  << focusable << std::endl;
4247     oss << "DecoStatus: "  << decoStatus << std::endl;
4248     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
4249     oss << "WindowRect: " << "[ "
4250         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4251         << " ]" << std::endl;
4252     oss << "scaleX: " << session->GetScaleX() << std::endl;
4253     oss << "scaleY: " << session->GetScaleY() << std::endl;
4254     oss << "Offset: " << "[ "
4255         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4256     oss << "Scale: " << "[ "
4257         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4258         << session->GetPivotX() << ", " << session->GetPivotY()
4259         << " ]" << std::endl;
4260     dumpInfo.append(oss.str());
4261 
4262     DumpSessionElementInfo(session, params, dumpInfo);
4263     return WSError::WS_OK;
4264 }
4265 
GetSCBDebugDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params)4266 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params)
4267 {
4268     std::string cmd = ScbDumpSubscriber::JoinCommands(params, params.size());
4269 
4270     // publish data
4271     bool ret = eventHandler_->PostSyncTask([this, cmd] { return g_scbSubscriber->Publish(cmd); }, "PublishSCBDumper");
4272     if (!ret) {
4273         return WSError::WS_ERROR_INVALID_OPERATION;
4274     }
4275 
4276     // get response event
4277     auto task = [this, &dumpInfo]() {
4278         dumpInfo.append(g_scbSubscriber->GetDebugDumpInfo(WAIT_TIME));
4279         return WSError::WS_OK;
4280     };
4281     eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4282 
4283     return WSError::WS_OK;
4284 }
4285 
NotifyDumpInfoResult(const std::vector<std::string> & info)4286 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4287 {
4288     dumpInfoFuture_.SetValue(info);
4289     WLOGFD("NotifyDumpInfoResult");
4290 }
4291 
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)4292 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4293 {
4294     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4295         WLOGFE("GetSessionDumpInfo permission denied!");
4296         return WSError::WS_ERROR_INVALID_PERMISSION;
4297     }
4298 
4299     if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4300         return GetAllSessionDumpInfo(dumpInfo);
4301     }
4302     if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4303         return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4304     }
4305     if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2:params num
4306         return GetSCBDebugDumpInfo(dumpInfo, params);
4307     }
4308     if (params.size() >= 2 && params[0] == ARG_DUMP_PIPLINE && IsValidDigitString(params[1])) { // 2: params num
4309         return GetTotalUITreeInfo(params[1], dumpInfo);
4310     }
4311     return WSError::WS_ERROR_INVALID_OPERATION;
4312 }
4313 
GetTotalUITreeInfo(const std::string & strId,std::string & dumpInfo)4314 WSError SceneSessionManager::GetTotalUITreeInfo(const std::string& strId, std::string& dumpInfo)
4315 {
4316     TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4317     uint64_t screenId = std::stoull(strId);
4318     if (dumpUITreeFunc_) {
4319         dumpUITreeFunc_(screenId, dumpInfo);
4320     } else {
4321         TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4322     }
4323     return WSError::WS_OK;
4324 }
4325 
SetDumpUITreeFunc(const DumpUITreeFunc & func)4326 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4327 {
4328     dumpUITreeFunc_ = func;
4329 }
4330 
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)4331 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
4332 {
4333     onFlushUIParamsFunc_ = std::move(func);
4334 }
4335 
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)4336 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
4337 {
4338     isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
4339 }
4340 
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)4341 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4342 {
4343     // notify RS
4344     WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4345         " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4346         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4347         sceneSession->GetSessionInfo().bundleName_.c_str(),
4348         sceneSession->GetSessionInfo().abilityName_.c_str(),
4349         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4350     uint64_t focusNodeId = 0; // 0 means invalid
4351     if (sceneSession->GetSurfaceNode() == nullptr) {
4352         WLOGFW("focused window surfaceNode is null");
4353     } else {
4354         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4355     }
4356     FocusAppInfo appInfo = {
4357         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4358         sceneSession->GetSessionInfo().bundleName_,
4359         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4360     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4361 }
4362 
4363 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4364 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4365 {
4366     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4367     {
4368         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4369         for (auto& iter : sceneSessionMap_) {
4370             ret.push_back(iter);
4371         }
4372     }
4373     std::sort(ret.begin(), ret.end(), cmp);
4374     return ret;
4375 }
4376 
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)4377 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4378 {
4379     if (isFromTopToBottom) {
4380         TraverseSessionTreeFromTopToBottom(func);
4381     } else {
4382         TraverseSessionTreeFromBottomToTop(func);
4383     }
4384     return;
4385 }
4386 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4387 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4388 {
4389     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4390         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4391         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4392         return lhsZOrder < rhsZOrder;
4393     };
4394     auto sceneSessionVector = GetSceneSessionVector(cmp);
4395 
4396     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
4397         auto session = iter->second;
4398         if (session == nullptr) {
4399             WLOGFE("session is nullptr");
4400             continue;
4401         }
4402         if (func(session)) {
4403             return;
4404         }
4405     }
4406     return;
4407 }
4408 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)4409 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
4410 {
4411     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4412     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4413         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4414         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4415         return lhsZOrder < rhsZOrder;
4416     };
4417     auto sceneSessionVector = GetSceneSessionVector(cmp);
4418     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
4419     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
4420         auto session = iter->second;
4421         if (session == nullptr) {
4422             WLOGFE("session is nullptr");
4423             continue;
4424         }
4425         if (func(session)) {
4426             return;
4427         }
4428     }
4429     return;
4430 }
4431 
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4432 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
4433     FocusChangeReason reason)
4434 {
4435     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4436     auto sceneSession = GetSceneSession(persistentId);
4437     if (sceneSession == nullptr) {
4438         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
4439         return WMError::WM_ERROR_NULLPTR;
4440     }
4441     int32_t callingPid = IPCSkeleton::GetCallingPid();
4442     if (callingPid != sceneSession->GetCallingPid() &&
4443         !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
4444         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
4445         return WMError::WM_ERROR_INVALID_CALLING;
4446     }
4447     auto task = [this, persistentId, isFocused, byForeground, reason]() {
4448         if (isFocused) {
4449             RequestSessionFocus(persistentId, byForeground, reason);
4450         } else {
4451             RequestSessionUnfocus(persistentId, reason);
4452         }
4453     };
4454     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
4455     focusChangeReason_ = reason;
4456     return WMError::WM_OK;
4457 }
4458 
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4459 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
4460     FocusChangeReason reason)
4461 {
4462     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4463     auto task = [this, persistentId, isFocused, byForeground, reason]() {
4464         if (isFocused) {
4465             if (reason == FocusChangeReason::FOREGROUND) {
4466                 RequestSessionFocusImmediately(persistentId);
4467                 return;
4468             }
4469             if (reason == FocusChangeReason::MOVE_UP) {
4470                 auto session = GetSceneSession(persistentId);
4471                 if (session && !session->IsFocused()) {
4472                     PostProcessFocusState state = { true, true, reason };
4473                     session->SetPostProcessFocusState(state);
4474                 }
4475                 return;
4476             }
4477             // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
4478             if (reason == FocusChangeReason::CLICK) {
4479                 return;
4480             }
4481             if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
4482                 auto session = GetSceneSession(persistentId);
4483                 if (session && !session->IsFocused()) {
4484                     PostProcessFocusState state = { true, true, reason };
4485                     session->SetPostProcessFocusState(state);
4486                 }
4487             }
4488         } else {
4489             RequestSessionUnfocus(persistentId, reason);
4490         }
4491     };
4492     taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
4493     return WMError::WM_OK;
4494 }
4495 
RequestAllAppSessionUnfocus()4496 void SceneSessionManager::RequestAllAppSessionUnfocus()
4497 {
4498     auto task = [this]() {
4499         RequestAllAppSessionUnfocusInner();
4500     };
4501     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
4502     return;
4503 }
4504 
4505 /**
4506  * request focus and ignore its state
4507  * only used when app main window start before foreground
4508 */
RequestSessionFocusImmediately(int32_t persistentId)4509 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
4510 {
4511     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
4512     // base block
4513     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4514     if (basicCheckRet != WSError::WS_OK) {
4515         return basicCheckRet;
4516     }
4517     auto sceneSession = GetSceneSession(persistentId);
4518     if (sceneSession == nullptr) {
4519         WLOGFE("[WMSComm]session is nullptr");
4520         return WSError::WS_ERROR_INVALID_SESSION;
4521     }
4522     if (!sceneSession->GetFocusable()) {
4523         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
4524         return WSError::WS_DO_NOTHING;
4525     }
4526     if (!sceneSession->IsFocusedOnShow()) {
4527         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4528         return WSError::WS_DO_NOTHING;
4529     }
4530 
4531     // specific block
4532     FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
4533     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
4534     if (specificCheckRet != WSError::WS_OK) {
4535         return specificCheckRet;
4536     }
4537 
4538     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4539     if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
4540         needBlockNotifyFocusStatusUntilForeground_ = true;
4541     }
4542     ShiftFocus(sceneSession, reason);
4543     return WSError::WS_OK;
4544 }
4545 
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)4546 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
4547 {
4548     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
4549         persistentId, byForeground, reason);
4550     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4551     if (basicCheckRet != WSError::WS_OK) {
4552         return basicCheckRet;
4553     }
4554     auto sceneSession = GetSceneSession(persistentId);
4555     if (sceneSession == nullptr) {
4556         WLOGFE("[WMSComm]session is nullptr");
4557         return WSError::WS_ERROR_INVALID_SESSION;
4558     }
4559     if (!sceneSession->GetFocusable() || !IsSessionVisibleForeground(sceneSession)) {
4560         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
4561         return WSError::WS_DO_NOTHING;
4562     }
4563     if (!sceneSession->IsFocusedOnShow()) {
4564         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4565         return WSError::WS_DO_NOTHING;
4566     }
4567     if (!sceneSession->IsFocusableOnShow() &&
4568         (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
4569         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
4570         return WSError::WS_DO_NOTHING;
4571     }
4572 
4573     // subwindow/dialog state block
4574     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4575         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4576         GetSceneSession(sceneSession->GetParentPersistentId()) &&
4577         !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
4578             TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
4579                 sceneSession->GetParentPersistentId());
4580             return WSError::WS_DO_NOTHING;
4581     }
4582     // specific block
4583     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
4584     if (specificCheckRet != WSError::WS_OK) {
4585         return specificCheckRet;
4586     }
4587 
4588     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4589     needBlockNotifyFocusStatusUntilForeground_ = false;
4590     ShiftFocus(sceneSession, reason);
4591     return WSError::WS_OK;
4592 }
4593 
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)4594 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
4595 {
4596     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
4597     if (persistentId == INVALID_SESSION_ID) {
4598         WLOGFE("id is invalid");
4599         return WSError::WS_ERROR_INVALID_SESSION;
4600     }
4601     auto focusedSession = GetSceneSession(focusedSessionId_);
4602     if (persistentId != focusedSessionId_ &&
4603         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
4604         TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
4605         return WSError::WS_DO_NOTHING;
4606     }
4607     // if pop menu created by desktop request unfocus, back to desktop
4608     auto lastSession = GetSceneSession(lastFocusedSessionId_);
4609     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
4610         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
4611         RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
4612             TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
4613             return WSError::WS_OK;
4614     }
4615     auto nextSession = GetNextFocusableSession(persistentId);
4616     if (nextSession == nullptr) {
4617         DumpAllSessionFocusableInfo(persistentId);
4618     }
4619 
4620     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4621     needBlockNotifyFocusStatusUntilForeground_ = false;
4622 
4623     if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
4624         return WSError::WS_OK;
4625     }
4626 
4627     return ShiftFocus(nextSession, reason);
4628 }
4629 
RequestAllAppSessionUnfocusInner()4630 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
4631 {
4632     TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
4633     auto focusedSession = GetSceneSession(focusedSessionId_);
4634     if (!focusedSession) {
4635         TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
4636         return WSError::WS_DO_NOTHING;
4637     }
4638     if (!focusedSession->IsAppSession()) {
4639         WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
4640         return WSError::WS_DO_NOTHING;
4641     }
4642     auto nextSession = GetTopFocusableNonAppSession();
4643 
4644     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4645     needBlockNotifyFocusStatusUntilForeground_ = false;
4646     return ShiftFocus(nextSession, FocusChangeReason::WIND);
4647 }
4648 
RequestFocusBasicCheck(int32_t persistentId)4649 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
4650 {
4651     // basic focus rule
4652     if (persistentId == INVALID_SESSION_ID) {
4653         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
4654         return WSError::WS_ERROR_INVALID_SESSION;
4655     }
4656     if (persistentId == focusedSessionId_) {
4657         TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
4658         return WSError::WS_DO_NOTHING;
4659     }
4660     return WSError::WS_OK;
4661 }
4662 
4663 /**
4664  * @note @window.focus
4665  * When high zOrder System Session unfocus, check if the last focused app window can focus.
4666  */
CheckLastFocusedAppSessionFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & nextSession)4667 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
4668     sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
4669 {
4670     if (focusedSession == nullptr || nextSession == nullptr) {
4671         return false;
4672     }
4673 
4674     TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
4675         lastFocusedAppSessionId_, nextSession->GetPersistentId());
4676 
4677     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
4678         return false;
4679     }
4680 
4681     if (!focusedSession->IsSystemSessionAboveApp()) {
4682         return false;
4683     }
4684 
4685     auto mode = nextSession->GetWindowMode();
4686     // only when next session is app, and in split or floation
4687     if (nextSession->IsAppSession() &&
4688         (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
4689          mode == WindowMode::WINDOW_MODE_FLOATING)) {
4690         if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
4691             WSError::WS_OK) {
4692             return true;
4693         }
4694         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
4695     }
4696     return false;
4697 }
4698 
4699 /**
4700  * When switching focus, check if the blockingType window has been  traversed downwards.
4701  *
4702  * @return true: traversed downwards, false: not.
4703  */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession> & requestSceneSession,sptr<SceneSession> & focusedSession,bool includingAppSession)4704 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
4705     sptr<SceneSession>& focusedSession, bool includingAppSession)
4706 {
4707     uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
4708     uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
4709     TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
4710         requestSessionZOrder, focusedSessionZOrder);
4711     if  (requestSessionZOrder < focusedSessionZOrder)  {
4712         auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
4713             includingAppSession);
4714         uint32_t topNearestBlockingZOrder = 0;
4715         if  (topNearestBlockingFocusSession)  {
4716             topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
4717             TLOGD(WmsLogTag::WMS_FOCUS,  "requestSessionZOrder: %{public}d, focusedSessionZOrder:  %{public}d\
4718                 topNearestBlockingZOrder:  %{public}d",  requestSessionZOrder,  focusedSessionZOrder,
4719                 topNearestBlockingZOrder);
4720         }
4721         if  (focusedSessionZOrder >=  topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder)  {
4722             TLOGD(WmsLogTag::WMS_FOCUS,  "focus pass through, needs to be intercepted");
4723             return true;
4724         }
4725     }
4726     TLOGD(WmsLogTag::WMS_FOCUS, "not through");
4727     return false;
4728 }
4729 
CheckTopmostWindowFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & sceneSession)4730 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
4731 {
4732     bool isFocusedMainSessionTopmost =
4733         focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
4734     auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
4735     bool isFocusedSessionParentTopmost = parentSession &&
4736         parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
4737     if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
4738         (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
4739         return true;
4740     }
4741     return false;
4742 }
4743 
CheckRequestFocusImmdediately(sptr<SceneSession> & sceneSession)4744 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
4745 {
4746     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4747          (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
4748         (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
4749          ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
4750         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
4751         return true;
4752     }
4753     return false;
4754 }
4755 
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)4756 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
4757     const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
4758 {
4759     if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
4760         focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
4761         return false;
4762     }
4763     if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
4764         return false;
4765     }
4766     return sceneSession->GetZOrder() < focusedSession->GetZOrder();
4767 }
4768 
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)4769 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
4770     FocusChangeReason reason)
4771 {
4772     TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
4773     int32_t persistentId = sceneSession->GetPersistentId();
4774     if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
4775         TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
4776         return WSError::WS_ERROR_INVALID_OPERATION;
4777     }
4778     // dialog get focus
4779     if (CheckRequestFocusImmdediately(sceneSession)) {
4780         return WSError::WS_DO_NOTHING;
4781     }
4782     // blocking-type session will block lower zOrder request focus
4783     auto focusedSession = GetSceneSession(focusedSessionId_);
4784     if (focusedSession) {
4785         TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d",  reason,
4786             byForeground);
4787         if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
4788             // return ok if focused session is topmost
4789             return WSError::WS_OK;
4790         }
4791         if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
4792             sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
4793             TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
4794             byForeground = false;
4795         }
4796         if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession,  focusedSession,  true))  {
4797             TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
4798             return WSError::WS_DO_NOTHING;
4799         }
4800         if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
4801             !byForeground)  {
4802             if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
4803                 && focusedSession->IsAppSession()) {
4804                 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
4805                 return WSError::WS_OK;
4806             }
4807         }
4808         bool isBlockingType = focusedSession->IsAppSession() ||
4809             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
4810         // temp check
4811         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
4812             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
4813                 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
4814                     persistentId);
4815                 return WSError::WS_DO_NOTHING;
4816         }
4817         // desktop click temp check
4818         if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
4819             TLOGW(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
4820             return WSError::WS_DO_NOTHING;
4821         }
4822     }
4823     return WSError::WS_OK;
4824 }
4825 
CheckParentSessionVisible(const sptr<SceneSession> & session)4826 bool SceneSessionManager::CheckParentSessionVisible(const sptr<SceneSession>& session)
4827 {
4828     if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
4829         session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4830         GetSceneSession(session->GetParentPersistentId()) &&
4831         !IsSessionVisibleForeground(GetSceneSession(session->GetParentPersistentId()))) {
4832         return false;
4833     }
4834     return true;
4835 }
4836 
DumpAllSessionFocusableInfo(int32_t persistentId)4837 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
4838 {
4839     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
4840     auto func = [this](sptr<SceneSession> session) {
4841         if (session == nullptr) {
4842             return false;
4843         }
4844         bool parentVisible = CheckParentSessionVisible(session);
4845         bool sessionVisible = IsSessionVisible(session);
4846         TLOGI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
4847             "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
4848             session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
4849             session->GetFocusable(), sessionVisible, parentVisible);
4850         return false;
4851     };
4852     TraverseSessionTree(func, true);
4853 }
4854 
GetNextFocusableSession(int32_t persistentId)4855 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
4856 {
4857     TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
4858     bool previousFocusedSessionFound = false;
4859     sptr<SceneSession> ret = nullptr;
4860     auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
4861         if (session == nullptr) {
4862             return false;
4863         }
4864         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
4865             TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
4866             return false;
4867         }
4868         if (previousFocusedSessionFound && session->GetFocusable() &&
4869             IsSessionVisibleForeground(session) && CheckParentSessionVisible(session)) {
4870             ret = session;
4871             return true;
4872         }
4873         if (session->GetPersistentId() == persistentId) {
4874             previousFocusedSessionFound = true;
4875         }
4876         return false;
4877     };
4878     TraverseSessionTree(func, true);
4879     return ret;
4880 }
4881 
4882 /**
4883  * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
4884  * and it is the closest;
4885  */
GetTopNearestBlockingFocusSession(uint32_t zOrder,bool includingAppSession)4886 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
4887 {
4888     sptr<SceneSession> ret = nullptr;
4889     auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
4890         if (session == nullptr) {
4891             return false;
4892         }
4893         uint32_t sessionZOrder = session->GetZOrder();
4894         if (sessionZOrder <= zOrder) { // must be above the target session
4895             return false;
4896         }
4897         if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4898             TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
4899             return false;
4900         }
4901         auto parentSession = GetSceneSession(session->GetParentPersistentId());
4902         if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
4903             parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
4904             parentSession->IsTopmost()) {
4905             TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
4906             return false;
4907         }
4908         bool isPhoneOrPad = systemConfig_.uiType_ == UI_TYPE_PHONE || systemConfig_.uiType_ == UI_TYPE_PAD;
4909         bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
4910                               (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
4911                               (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
4912         if (IsSessionVisibleForeground(session) && isBlockingType)  {
4913             ret = session;
4914             return true;
4915         }
4916         return false;
4917     };
4918     TraverseSessionTree(func, false);
4919     return ret;
4920 }
4921 
GetTopFocusableNonAppSession()4922 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
4923 {
4924     TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
4925     sptr<SceneSession> ret = nullptr;
4926     auto func = [this, &ret](sptr<SceneSession> session) {
4927         if (session == nullptr) {
4928             return false;
4929         }
4930         if (session->IsAppSession()) {
4931             return true;
4932         }
4933         if (session->GetFocusable() && IsSessionVisibleForeground(session)) {
4934             ret = session;
4935         }
4936         return false;
4937     };
4938     TraverseSessionTree(func, false);
4939     return ret;
4940 }
4941 
SetShiftFocusListener(const ProcessShiftFocusFunc & func)4942 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
4943 {
4944     TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
4945     shiftFocusFunc_ = func;
4946 }
4947 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)4948 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
4949 {
4950     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
4951     notifySCBAfterFocusedFunc_ = func;
4952 }
4953 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)4954 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
4955 {
4956     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
4957     notifySCBAfterUnfocusedFunc_ = func;
4958 }
4959 
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)4960 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
4961 {
4962     WLOGFD("SetCallingSessionIdSessionListenser");
4963     callingSessionIdChangeFunc_ = func;
4964 }
4965 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)4966 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
4967 {
4968     WLOGFD("SetStartUIAbilityErrorListener");
4969     startUIAbilityErrorFunc_ = func;
4970 }
4971 
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)4972 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
4973     const AbilityManagerCollaboratorRegisteredFunc& func)
4974 {
4975     auto task = [this, func] {
4976         abilityManagerCollaboratorRegisteredFunc_ = func;
4977     };
4978     taskScheduler_->PostAsyncTask(task, __func__);
4979 }
4980 
ShiftFocus(sptr<SceneSession> & nextSession,FocusChangeReason reason)4981 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)
4982 {
4983     // unfocus
4984     int32_t focusedId = focusedSessionId_;
4985     auto focusedSession = GetSceneSession(focusedSessionId_);
4986     UpdateFocusStatus(focusedSession, false);
4987     // focus
4988     int32_t nextId = INVALID_SESSION_ID;
4989     if (nextSession == nullptr) {
4990         std::string sessionLog(GetAllSessionFocusInfo());
4991         TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
4992             focusedSessionId_, sessionLog.c_str());
4993     } else {
4994         nextId = nextSession->GetPersistentId();
4995     }
4996     UpdateFocusStatus(nextSession, true);
4997     if (shiftFocusFunc_ != nullptr) {
4998         shiftFocusFunc_(nextId);
4999     }
5000     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5001     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5002     AnomalyDetection::FocusCheckProcess(focusedId, nextId);
5003     if (!scbPrevFocus && scbCurrFocus) {
5004         if (notifySCBAfterFocusedFunc_ != nullptr) {
5005             notifySCBAfterFocusedFunc_();
5006         }
5007     } else if (scbPrevFocus && !scbCurrFocus) {
5008         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5009             notifySCBAfterUnfocusedFunc_();
5010         }
5011     }
5012     TLOGI(WmsLogTag::WMS_FOCUS, "ShiftFocus, focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5013         focusedId, nextId, reason);
5014     return WSError::WS_OK;
5015 }
5016 
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5017 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5018 {
5019     if (sceneSession == nullptr) {
5020         if (isFocused) {
5021             SetFocusedSessionId(INVALID_SESSION_ID);
5022             lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5023         }
5024         return;
5025     }
5026     TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5027         sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5028     // set focused
5029     if (isFocused) {
5030         SetFocusedSessionId(sceneSession->GetPersistentId());
5031         if (sceneSession->IsAppOrLowerSystemSession()) {
5032             lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5033         }
5034     }
5035     sceneSession->UpdateFocus(isFocused);
5036     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5037         NotifyFocusStatus(sceneSession, isFocused);
5038     }
5039 }
5040 
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5041 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5042 {
5043     if (sceneSession == nullptr) {
5044         WLOGFE("[WMSComm]session is nullptr");
5045         if (isFocused) {
5046             auto prevSession = GetSceneSession(lastFocusedSessionId_);
5047             NotifyUnFocusedByMission(prevSession);
5048         }
5049         return;
5050     }
5051     int32_t persistentId = sceneSession->GetPersistentId();
5052 
5053     TLOGI(WmsLogTag::WMS_FOCUS,
5054         "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5055         sceneSession->GetSessionInfo().bundleName_.c_str(),
5056         sceneSession->GetSessionInfo().abilityName_.c_str(),
5057         sceneSession->GetWindowNameAllType().c_str(),
5058         persistentId, isFocused);
5059     if (isFocused) {
5060         if (IsSessionVisibleForeground(sceneSession)) {
5061             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5062         }
5063         UpdateBrightness(focusedSessionId_);
5064         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5065     }
5066     // notify window manager
5067     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5068         sceneSession->GetWindowId(),
5069         static_cast<DisplayId>(0),
5070         sceneSession->GetCallingPid(),
5071         sceneSession->GetCallingUid(),
5072         sceneSession->GetWindowType(),
5073         sceneSession->GetAbilityToken()
5074     );
5075     SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5076     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5077     sceneSession->NotifyFocusStatus(isFocused);
5078     // notify listenerController
5079     auto prevSession = GetSceneSession(lastFocusedSessionId_);
5080     if (isFocused && MissionChanged(prevSession, sceneSession)) {
5081         NotifyFocusStatusByMission(prevSession, sceneSession);
5082     }
5083 }
5084 
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)5085 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5086     const std::string& reason)
5087 {
5088     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5089     nlohmann::json payload;
5090     payload.emplace("uid", uid);
5091     payload.emplace("bundleName", bundleName);
5092     payload.emplace("reason", reason);
5093     nlohmann::json reply;
5094     int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5095     return ret;
5096 }
5097 
NotifyFocusStatusByMission(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5098 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5099 {
5100     if (listenerController_ != nullptr) {
5101         if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5102             TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", prevSession->GetMissionId());
5103             listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5104         }
5105         if (currSession && !currSession->GetSessionInfo().isSystem_) {
5106             TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionFocused, id: %{public}d", currSession->GetMissionId());
5107             listenerController_->NotifySessionFocused(currSession->GetMissionId());
5108         }
5109     }
5110 }
5111 
NotifyUnFocusedByMission(sptr<SceneSession> & sceneSession)5112 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5113 {
5114     if (listenerController_ == nullptr) {
5115         return;
5116     }
5117     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5118         TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", sceneSession->GetMissionId());
5119         listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5120     }
5121 }
5122 
MissionChanged(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5123 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5124 {
5125     if (prevSession == nullptr && currSession == nullptr) {
5126         return false;
5127     }
5128     if (prevSession == nullptr || currSession == nullptr) {
5129         return true;
5130     }
5131     return prevSession->GetMissionId() != currSession->GetMissionId();
5132 }
5133 
GetAllSessionFocusInfo()5134 std::string SceneSessionManager::GetAllSessionFocusInfo()
5135 {
5136     std::ostringstream os;
5137     auto func = [&os](sptr<SceneSession> session) {
5138         if (session == nullptr) {
5139             WLOGE("sceneSession is nullptr");
5140             return false;
5141         }
5142         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5143            " ,focusable: "<< session->GetFocusable() << ";";
5144         return false;
5145     };
5146     TraverseSessionTree(func, true);
5147     return os.str();
5148 }
5149 
UpdateFocus(int32_t persistentId,bool isFocused)5150 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5151 {
5152     auto task = [this, persistentId, isFocused]() {
5153         // notify session and client
5154         auto sceneSession = GetSceneSession(persistentId);
5155         if (sceneSession == nullptr) {
5156             WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5157             return WSError::WS_ERROR_INVALID_WINDOW;
5158         }
5159         WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5160             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5161         // focusId change
5162         if (isFocused) {
5163             SetFocusedSessionId(persistentId);
5164             UpdateBrightness(focusedSessionId_);
5165             FocusIDChange(persistentId, sceneSession);
5166         } else if (persistentId == GetFocusedSessionId()) {
5167             SetFocusedSessionId(INVALID_SESSION_ID);
5168         }
5169         // notify window manager
5170         sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5171             sceneSession->GetWindowId(),
5172             static_cast<DisplayId>(0),
5173             sceneSession->GetCallingPid(),
5174             sceneSession->GetCallingUid(),
5175             sceneSession->GetWindowType(),
5176             sceneSession->GetAbilityToken()
5177         );
5178         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5179         WSError res = WSError::WS_OK;
5180         res = sceneSession->UpdateFocus(isFocused);
5181         if (res != WSError::WS_OK) {
5182             return res;
5183         }
5184         WLOGFI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5185                sceneSession->GetSessionInfo().isSystem_);
5186         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
5187             if (isFocused) {
5188                 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
5189                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5190             } else {
5191                 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5192                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5193             }
5194         }
5195         return WSError::WS_OK;
5196     };
5197 
5198     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5199     return WSError::WS_OK;
5200 }
5201 
UpdateWindowMode(int32_t persistentId,int32_t windowMode)5202 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5203 {
5204     WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
5205     auto sceneSession = GetSceneSession(persistentId);
5206     if (sceneSession == nullptr) {
5207         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
5208         return WSError::WS_ERROR_INVALID_WINDOW;
5209     }
5210     WindowMode mode = static_cast<WindowMode>(windowMode);
5211     return sceneSession->UpdateWindowMode(mode);
5212 }
5213 
5214 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)5215 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
5216     MMI::PointerEvent::PointerItem& pointerItem)
5217 {
5218     struct PointerEventData {
5219         double x;
5220         double y;
5221         uint64_t time;
5222     } pointerEventData = {
5223         .x = pointerItem.GetDisplayX(),
5224         .y = pointerItem.GetDisplayY(),
5225         .time = pointerEvent->GetActionTime()
5226     };
5227 
5228     const uint32_t MAX_HMAC_SIZE = 64;
5229     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
5230     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
5231     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
5232     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
5233         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
5234         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
5235     }
5236 }
5237 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
5238 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)5239 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
5240 {
5241     if (!pointerEvent) {
5242         WLOGFE("pointerEvent is null");
5243         return WSError::WS_ERROR_NULLPTR;
5244     }
5245     MMI::PointerEvent::PointerItem pointerItem;
5246     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
5247         WLOGFE("Failed to get pointerItem");
5248         return WSError::WS_ERROR_INVALID_PARAM;
5249     }
5250 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
5251     FillSecCompEnhanceData(pointerEvent, pointerItem);
5252 #endif
5253     TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d,action=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
5254         pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
5255     pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
5256     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
5257     return WSError::WS_OK;
5258 }
5259 
SetScreenLocked(const bool isScreenLocked)5260 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
5261 {
5262     isScreenLocked_ = isScreenLocked;
5263     DeleteStateDetectTask();
5264 }
5265 
DeleteStateDetectTask()5266 void SceneSessionManager::DeleteStateDetectTask()
5267 {
5268     if (!IsScreenLocked()) {
5269         return;
5270     }
5271     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5272     for (auto iter : sceneSessionMap_) {
5273         auto& session = iter.second;
5274         if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
5275             taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
5276             DetectTaskInfo detectTaskInfo;
5277             session->SetDetectTaskInfo(detectTaskInfo);
5278         }
5279     }
5280 }
5281 
IsScreenLocked() const5282 bool SceneSessionManager::IsScreenLocked() const
5283 {
5284     return isScreenLocked_;
5285 }
5286 
RegisterWindowChanged(const WindowChangedFunc & func)5287 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
5288 {
5289     WindowChangedFunc_ = func;
5290 }
5291 
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)5292 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
5293     const std::unordered_set<std::string>& privacyBundles)
5294 {
5295     bool needNotify = false;
5296     static int reSendTimes = MAX_RESEND_TIMES;
5297     std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
5298     do {
5299         if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
5300             TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
5301             needNotify = !privacyBundles.empty();
5302             break;
5303         }
5304         const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
5305         if (lastPrivacyBundles.size() != privacyBundles.size()) {
5306             TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
5307                   lastPrivacyBundles.size(), privacyBundles.size());
5308             needNotify = true;
5309             break;
5310         }
5311         for (const auto& bundle : lastPrivacyBundles) {
5312             if (privacyBundles.find(bundle) == privacyBundles.end()) {
5313                 needNotify = true;
5314                 break;
5315             }
5316         }
5317     } while (false);
5318 
5319     TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
5320           displayId, needNotify);
5321     if (needNotify) {
5322         reSendTimes = MAX_RESEND_TIMES;
5323         privacyBundleMap_[displayId] = privacyBundles;
5324     } else if (reSendTimes > 0) {
5325         needNotify = true;
5326         reSendTimes--;
5327         privacyBundleMap_[displayId] = privacyBundles;
5328     }
5329     return needNotify;
5330 }
5331 
UpdatePrivateStateAndNotify(uint32_t persistentId)5332 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
5333 {
5334     auto sceneSession = GetSceneSession(persistentId);
5335     if (sceneSession == nullptr) {
5336         TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
5337         return;
5338     }
5339 
5340     auto sessionProperty = sceneSession->GetSessionProperty();
5341     if (sessionProperty == nullptr) {
5342         TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
5343         return;
5344     }
5345     auto displayId = sessionProperty->GetDisplayId();
5346     std::unordered_set<std::string> privacyBundleList;
5347     GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5348     if (!JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
5349         return;
5350     }
5351 
5352     std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
5353     ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5354         !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
5355     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
5356     if (!bundleListForNotify.empty()) {
5357         TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
5358     }
5359     for (const auto& bundle : bundleListForNotify) {
5360         TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
5361               displayId, bundle.c_str());
5362     }
5363 }
5364 
UpdatePrivateStateAndNotifyForAllScreens()5365 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
5366 {
5367     auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
5368     for (auto& iter : screenProperties) {
5369         auto displayId = iter.first;
5370         std::unordered_set<std::string> privacyBundleList;
5371         GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5372 
5373         ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5374             !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
5375     }
5376 }
5377 
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)5378 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
5379     std::unordered_set<std::string>& privacyBundles)
5380 {
5381     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5382     for (const auto& item : sceneSessionMap_) {
5383         sptr<SceneSession> sceneSession = item.second;
5384         if (sceneSession == nullptr) {
5385             TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
5386             continue;
5387         }
5388         auto sessionProperty = sceneSession->GetSessionProperty();
5389         if (sessionProperty == nullptr) {
5390             TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
5391             continue;
5392         }
5393         auto currentDisplayId = sessionProperty->GetDisplayId();
5394         if (displayId != currentDisplayId) {
5395             continue;
5396         }
5397         bool isForeground =  sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5398             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
5399         if (isForeground && sceneSession->GetParentSession() != nullptr) {
5400             isForeground = isForeground &&
5401                 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
5402                 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
5403         }
5404         bool isPrivate = sessionProperty->GetPrivacyMode() ||
5405             sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
5406         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
5407         if ((isForeground || IsSystemWindowVisible) && isPrivate) {
5408             if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
5409                 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
5410             } else {
5411                 TLOGD(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
5412                 privacyBundles.insert(sceneSession->GetWindowName());
5413             }
5414         }
5415     }
5416 }
5417 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5418 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5419 {
5420     NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
5421         this->OnSessionStateChange(persistentId, state);
5422     };
5423     if (sceneSession == nullptr) {
5424         WLOGFE("session is nullptr");
5425         return;
5426     }
5427     sceneSession->SetSessionStateChangeNotifyManagerListener(func);
5428     WLOGFD("RegisterSessionStateChangeFunc success");
5429 }
5430 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5431 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5432 {
5433     wptr<SceneSessionManager> weakSessionManager = this;
5434     NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
5435         auto sceneSessionManager = weakSessionManager.promote();
5436         if (sceneSessionManager == nullptr) {
5437             return;
5438         }
5439         sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
5440     };
5441     if (sceneSession == nullptr) {
5442         WLOGFE("session is nullptr");
5443         return;
5444     }
5445     sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
5446 }
5447 
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)5448 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5449 {
5450     NotifyRequestFocusStatusNotifyManagerFunc func =
5451     [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
5452         this->RequestFocusStatus(persistentId, isFocused, byForeground, reason);
5453     };
5454     if (sceneSession == nullptr) {
5455         WLOGFE("session is nullptr");
5456         return;
5457     }
5458     sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
5459     WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
5460 }
5461 
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)5462 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
5463 {
5464     GetStateFromManagerFunc func = [this](const ManagerState key) {
5465         switch (key)
5466         {
5467         case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
5468             return this->IsScreenLocked();
5469             break;
5470         default:
5471             return false;
5472             break;
5473         }
5474     };
5475     if (sceneSession == nullptr) {
5476         WLOGFE("session is nullptr");
5477         return;
5478     }
5479     sceneSession->SetGetStateFromManagerListener(func);
5480     WLOGFD("RegisterGetStateFromManagerFunc success");
5481 }
5482 
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)5483 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5484 {
5485     SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
5486         const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
5487         if (sceneSession == nullptr || property == nullptr) {
5488             TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
5489             return;
5490         }
5491         switch (action) {
5492             case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
5493                 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
5494                 break;
5495             case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
5496             case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
5497             case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
5498             case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
5499             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
5500             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
5501                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5502                 break;
5503             case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
5504                 SetBrightness(sceneSession, property->GetBrightness());
5505                 break;
5506             case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
5507             case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
5508                 UpdatePrivateStateAndNotify(property->GetPersistentId());
5509                 break;
5510             case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
5511                 CheckAndNotifyWaterMarkChangedResult();
5512                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5513                 break;
5514             case WSPropertyChangeAction::ACTION_UPDATE_MODE:
5515                 if (sceneSession->GetSessionProperty() != nullptr) {
5516                     ProcessWindowModeType();
5517                 }
5518                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5519                 break;
5520             case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5521                 HandleHideNonSystemFloatingWindows(property, sceneSession);
5522                 break;
5523             case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
5524                 FlushWindowInfoToMMI();
5525                 break;
5526             default:
5527                 break;
5528         }
5529     };
5530     if (sceneSession != nullptr) {
5531         sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
5532     }
5533 }
5534 
OnSessionStateChange(int32_t persistentId,const SessionState & state)5535 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
5536     int32_t persistentId, const SessionState& state)
5537 {
5538     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
5539     WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
5540     auto sceneSession = GetSceneSession(persistentId);
5541     if (sceneSession == nullptr) {
5542         WLOGFD("session is nullptr");
5543         return;
5544     }
5545     switch (state) {
5546         case SessionState::STATE_FOREGROUND:
5547             ProcessFocusWhenForeground(sceneSession);
5548             if (!IsSessionVisibleForeground(sceneSession)) {
5549                 sceneSession->SetPostProcessProperty(true);
5550                 break;
5551             }
5552             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
5553             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
5554             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
5555             UpdatePrivateStateAndNotify(persistentId);
5556             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5557                 ProcessSubSessionForeground(sceneSession);
5558             }
5559             break;
5560         case SessionState::STATE_BACKGROUND:
5561             NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
5562             RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
5563             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
5564             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
5565             HandleKeepScreenOn(sceneSession, false);
5566             UpdatePrivateStateAndNotify(persistentId);
5567             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5568                 ProcessSubSessionBackground(sceneSession);
5569             }
5570             break;
5571         default:
5572             break;
5573     }
5574     ProcessWindowModeType();
5575 }
5576 
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)5577 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
5578 {
5579     auto persistentId = sceneSession->GetPersistentId();
5580     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5581         persistentId == focusedSessionId_) {
5582         if (needBlockNotifyFocusStatusUntilForeground_) {
5583             needBlockNotifyUnfocusStatus_ = false;
5584             needBlockNotifyFocusStatusUntilForeground_ = false;
5585             NotifyFocusStatus(sceneSession, true);
5586         }
5587     } else if (!sceneSession->IsFocusedOnShow()) {
5588         sceneSession->SetFocusedOnShow(true);
5589     } else {
5590         if (Session::IsScbCoreEnabled()) {
5591             ProcessFocusWhenForegroundScbCore(sceneSession);
5592         } else {
5593             RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5594         }
5595         RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5596     }
5597 }
5598 
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)5599 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
5600 {
5601     if (sceneSession == nullptr) {
5602         TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
5603         return;
5604     }
5605     if (sceneSession->IsFocusableOnShow()) {
5606         if (IsSessionVisibleForeground(sceneSession)) {
5607             RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
5608         } else {
5609             PostProcessFocusState state = {true, true, FocusChangeReason::APP_FOREGROUND};
5610             sceneSession->SetPostProcessFocusState(state);
5611         }
5612     } else {
5613         TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
5614             sceneSession->GetPersistentId());
5615     }
5616 }
5617 
ProcessWindowModeType()5618 void SceneSessionManager::ProcessWindowModeType()
5619 {
5620     if (isScreenLocked_) {
5621         return;
5622     }
5623     NotifyRSSWindowModeTypeUpdate();
5624 }
5625 
IsSmallFoldProduct()5626 static bool IsSmallFoldProduct()
5627 {
5628     static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
5629     if (foldScreenType.empty()) {
5630         TLOGE(WmsLogTag::DEFAULT, "foldScreenType is empty");
5631         return false;
5632     }
5633     return foldScreenType[0] == '2';
5634 }
5635 
IsInSecondaryScreen(const sptr<SceneSession> & sceneSession)5636 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
5637 {
5638     auto sessionProperty = sceneSession->GetSessionProperty();
5639     if (sessionProperty == nullptr) {
5640         TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
5641         return false;
5642     }
5643     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5644     return sessionProperty->GetDisplayId() != defaultScreenId;
5645 }
5646 
CheckWindowModeType()5647 WindowModeType SceneSessionManager::CheckWindowModeType()
5648 {
5649     bool inSplit = false;
5650     bool inFloating = false;
5651     bool fullScreen = false;
5652     bool isSmallFold = IsSmallFoldProduct();
5653     {
5654         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5655         for (const auto& session : sceneSessionMap_) {
5656             if (session.second == nullptr ||
5657                 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
5658                 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
5659                 continue;
5660             }
5661             if (isSmallFold && IsInSecondaryScreen(session.second)) {
5662                 continue;
5663             }
5664             auto mode = session.second->GetWindowMode();
5665             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
5666                 inSplit = true;
5667             }
5668             if (mode == WindowMode::WINDOW_MODE_FLOATING) {
5669                 inFloating = true;
5670             }
5671             if (WindowHelper::IsFullScreenWindow(mode)) {
5672                 fullScreen = true;
5673             }
5674         }
5675     }
5676 
5677     WindowModeType type;
5678     if (inSplit) {
5679         if (inFloating) {
5680             type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
5681         } else {
5682             type = WindowModeType::WINDOW_MODE_SPLIT;
5683         }
5684     } else {
5685         if (inFloating) {
5686             if (fullScreen) {
5687                 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
5688             } else {
5689                 type = WindowModeType::WINDOW_MODE_FLOATING;
5690             }
5691         } else if (fullScreen) {
5692             type = WindowModeType::WINDOW_MODE_FULLSCREEN;
5693         } else {
5694             type = WindowModeType::WINDOW_MODE_OTHER;
5695         }
5696     }
5697     return type;
5698 }
5699 
NotifyRSSWindowModeTypeUpdate()5700 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
5701 {
5702     WindowModeType type = CheckWindowModeType();
5703     if (lastWindowModeType_ == type) {
5704         return;
5705     }
5706     lastWindowModeType_ = type;
5707     TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
5708         static_cast<uint8_t>(type));
5709     SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
5710 }
5711 
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)5712 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
5713 {
5714     if (sceneSession == nullptr) {
5715         WLOGFD("session is nullptr");
5716         return;
5717     }
5718     std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
5719     for (const auto& subSession : sceneSession->GetSubSession()) {
5720         if (subSession == nullptr) {
5721             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
5722             continue;
5723         }
5724         if (subSession->IsTopmost()) {
5725             modalVec.push_back(subSession);
5726             TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
5727             continue;
5728         }
5729         const auto& state = subSession->GetSessionState();
5730         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5731             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
5732             continue;
5733         }
5734         RequestSessionFocus(subSession->GetPersistentId(), true);
5735         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5736         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
5737     }
5738 
5739     for (const auto& modal : modalVec) {
5740         if (modal == nullptr) {
5741             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
5742             continue;
5743         }
5744         const auto& state = modal->GetSessionState();
5745         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5746             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
5747             continue;
5748         }
5749         auto modalSession = GetSceneSession(modal->GetPersistentId());
5750         if (modalSession == nullptr) {
5751             TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
5752             continue;
5753         }
5754         NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5755         if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
5756             needBlockNotifyUnfocusStatus_ = false;
5757             needBlockNotifyFocusStatusUntilForeground_ = false;
5758             NotifyFocusStatus(modalSession, true);
5759         }
5760         HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
5761     }
5762 }
5763 
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5764 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5765 {
5766     // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
5767     sptr<SceneSession> mainSession = nullptr;
5768     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5769         mainSession = sceneSession;
5770     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5771         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5772     }
5773     if (mainSession == nullptr) {
5774         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5775         return WSError::WS_DO_NOTHING;
5776     }
5777 
5778     std::vector<sptr<SceneSession>> topmostVec;
5779     for (auto subSession : mainSession->GetSubSession()) {
5780         if (subSession && subSession->IsTopmost()) {
5781             topmostVec.push_back(subSession);
5782         }
5783     }
5784     if (std::find_if(topmostVec.begin(), topmostVec.end(),
5785         [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5786         != topmostVec.end()) {
5787             TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
5788             return WSError::WS_OK;
5789     }
5790     WSError ret = WSError::WS_DO_NOTHING;
5791     for (auto topmostSession : topmostVec) {
5792         if (topmostSession == nullptr) {
5793             continue;
5794         }
5795         // no need to consider order, since rule of zOrder
5796         if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
5797             ret = WSError::WS_OK;
5798         }
5799     }
5800     return ret;
5801 }
5802 
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5803 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5804 {
5805     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
5806     sptr<SceneSession> mainSession = nullptr;
5807     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5808         mainSession = sceneSession;
5809     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5810         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5811     }
5812     if (mainSession == nullptr) {
5813         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5814         return WSError::WS_DO_NOTHING;
5815     }
5816     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
5817     if (std::find_if(dialogVec.begin(), dialogVec.end(),
5818         [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5819         != dialogVec.end()) {
5820             TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
5821             return WSError::WS_OK;
5822     }
5823     WSError ret = WSError::WS_DO_NOTHING;
5824     for (auto dialog : dialogVec) {
5825         if (dialog == nullptr) {
5826             continue;
5827         }
5828         // no need to consider order, since rule of zOrder
5829         if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
5830             ret = WSError::WS_OK;
5831         }
5832     }
5833     return ret;
5834 }
5835 
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)5836 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
5837 {
5838     if (sceneSession == nullptr) {
5839         WLOGFD("session is nullptr");
5840         return;
5841     }
5842     for (const auto& subSession : sceneSession->GetSubSession()) {
5843         if (subSession == nullptr) {
5844             WLOGFD("sub session is nullptr");
5845             continue;
5846         }
5847         const auto& state = subSession->GetSessionState();
5848         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5849             WLOGFD("sub session is not active");
5850             continue;
5851         }
5852         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5853         HandleKeepScreenOn(subSession, false);
5854         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
5855     }
5856     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
5857     for (const auto& dialog : dialogVec) {
5858         if (dialog == nullptr) {
5859             TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
5860             continue;
5861         }
5862         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
5863         if (dialogSession == nullptr) {
5864             TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
5865             continue;
5866         }
5867         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5868         HandleKeepScreenOn(dialogSession, false);
5869         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
5870     }
5871     for (const auto& toastSession : sceneSession->GetToastSession()) {
5872         if (toastSession == nullptr) {
5873             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
5874             continue;
5875         }
5876         const auto& state = toastSession->GetSessionState();
5877         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5878             continue;
5879         }
5880         NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5881         HandleKeepScreenOn(toastSession, false);
5882         UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
5883         toastSession->SetActive(false);
5884         toastSession->BackgroundTask();
5885     }
5886 }
5887 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)5888 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
5889     const sptr<WindowSessionProperty>& property)
5890 {
5891     if (sceneSession == nullptr) {
5892         WLOGFD("session is nullptr");
5893         return WSError::WS_ERROR_NULLPTR;
5894     }
5895     auto sessionProperty = sceneSession->GetSessionProperty();
5896     if (sessionProperty == nullptr) {
5897         return WSError::WS_ERROR_NULLPTR;
5898     }
5899     uint32_t flags = property->GetWindowFlags();
5900     uint32_t oldFlags = sessionProperty->GetWindowFlags();
5901     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
5902         (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
5903         !property->GetSystemCalling()) {
5904             WLOGFE("Set window flags permission denied");
5905             return WSError::WS_ERROR_NOT_SYSTEM_APP;
5906     }
5907     sessionProperty->SetWindowFlags(flags);
5908     CheckAndNotifyWaterMarkChangedResult();
5909     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
5910         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
5911     }
5912     WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
5913     return WSError::WS_OK;
5914 }
5915 
CheckAndNotifyWaterMarkChangedResult()5916 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
5917 {
5918     bool currentWaterMarkShowState = false;
5919     {
5920         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5921         for (const auto& iter: sceneSessionMap_) {
5922             auto& session = iter.second;
5923             if (!session) {
5924                 continue;
5925             }
5926             auto sessionProperty = session->GetSessionProperty();
5927             if (!sessionProperty) {
5928                 continue;
5929             }
5930             bool hasWaterMark = sessionProperty->GetWindowFlags() &
5931                 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
5932             bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
5933             if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
5934                 currentWaterMarkShowState = true;
5935                 break;
5936             }
5937         }
5938         if (combinedExtWindowFlags_.waterMarkFlag) {
5939             TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
5940             currentWaterMarkShowState = true;
5941         }
5942     }
5943     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
5944         lastWaterMarkShowState_ = currentWaterMarkShowState;
5945         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
5946     }
5947 }
5948 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)5949 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
5950 {
5951     WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
5952     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
5953     return WSError::WS_OK;
5954 }
5955 
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const5956 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
5957 {
5958     if (!bundleMgr_) {
5959         WLOGFE("bundle manager is nullptr.");
5960         return;
5961     }
5962 
5963     AAFwk::Want want;
5964     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
5965     auto uid = abilityInfo.uid;
5966     want.SetParam("uid", uid);
5967     bundleMgr_->ProcessPreload(want);
5968 }
5969 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)5970 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
5971 {
5972     auto scnSession = GetSceneSession(persistentId);
5973     if (scnSession == nullptr) {
5974         TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
5975         return;
5976     }
5977 
5978     const auto& sessionInfo = scnSession->GetSessionInfo();
5979     if (IsAtomicServiceFreeInstall(sessionInfo)) {
5980         TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
5981             scnSession->GetPersistentId(), scnSession->GetWindowType());
5982         FillSessionInfo(scnSession);
5983     }
5984 
5985     TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
5986         scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
5987         sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
5988     auto abilityInfoPtr = sessionInfo.abilityInfo;
5989     if (abilityInfoPtr == nullptr) {
5990         TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
5991         return;
5992     }
5993     if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
5994         !(abilityInfoPtr->excludeFromMissions)) {
5995         WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
5996         listenerController_->NotifySessionCreated(persistentId);
5997     }
5998 
5999     if (eventHandler_ != nullptr) {
6000         auto task = [persistentId]() {
6001             AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6002         };
6003         WLOGFI("Post CompleteFirstFrameDrawing task.");
6004         bool ret = eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6005         if (!ret) {
6006             WLOGFE("Report post first frame task failed. the task name is CompleteFirstFrameDrawing");
6007         }
6008     }
6009 
6010     if (taskScheduler_ == nullptr) {
6011         return;
6012     }
6013     auto task = [this, abilityInfoPtr]() {
6014         ProcessPreload(*abilityInfoPtr);
6015     };
6016     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6017 }
6018 
NotifySessionMovedToFront(int32_t persistentId)6019 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6020 {
6021     WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
6022     auto scnSession = GetSceneSession(persistentId);
6023     if (scnSession == nullptr) {
6024         WLOGFE("session is invalid with %{public}d", persistentId);
6025         return;
6026     }
6027     WLOGFI("NotifySessionMovedToFront, id: %{public}d, system: %{public}d", scnSession->GetPersistentId(),
6028            scnSession->GetSessionInfo().isSystem_);
6029     if (listenerController_ != nullptr &&
6030         !scnSession->GetSessionInfo().isSystem_ &&
6031         (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
6032         !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6033         listenerController_->NotifySessionMovedToFront(persistentId);
6034     }
6035 }
6036 
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)6037 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6038 {
6039     WLOGFI("Enter label: %{public}s", label.c_str());
6040 
6041     auto task = [this, &token, &label]() {
6042         auto sceneSession = FindSessionByToken(token);
6043         if (sceneSession == nullptr) {
6044             WLOGFI("fail to find session by token");
6045             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6046         }
6047         sceneSession->SetSessionLabel(label);
6048         WLOGFI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6049             sceneSession->GetSessionInfo().isSystem_);
6050         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
6051             WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6052             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6053         }
6054         return WSError::WS_OK;
6055     };
6056     return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6057 }
6058 
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)6059 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6060     const std::shared_ptr<Media::PixelMap>& icon)
6061 {
6062     WLOGFI("Enter");
6063     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6064         WLOGFE("The caller is not system-app, can not use system-api");
6065         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6066     }
6067 
6068     auto task = [this, &token, &icon]() {
6069         auto sceneSession = FindSessionByToken(token);
6070         if (sceneSession == nullptr) {
6071             WLOGFI("fail to find session by token");
6072             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6073         }
6074         sceneSession->SetSessionIcon(icon);
6075         WLOGFI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6076             sceneSession->GetSessionInfo().isSystem_);
6077         if (listenerController_ != nullptr &&
6078             !sceneSession->GetSessionInfo().isSystem_ &&
6079             (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
6080             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6081             WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6082             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6083         }
6084         return WSError::WS_OK;
6085     };
6086     return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6087 }
6088 
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)6089 WSError SceneSessionManager::IsValidSessionIds(
6090     const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6091 {
6092     WLOGFI("Enter");
6093     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6094     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6095         auto search = sceneSessionMap_.find(sessionIds.at(i));
6096         if (search == sceneSessionMap_.end() || search->second == nullptr) {
6097             results.push_back(false);
6098             continue;
6099         }
6100         results.push_back(true);
6101     }
6102     return WSError::WS_OK;
6103 }
6104 
RegisterSessionListener(const sptr<ISessionListener> & listener)6105 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6106 {
6107     WLOGFI("Enter");
6108     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6109         WLOGFE("The caller is not system-app, can not use system-api");
6110         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6111     }
6112     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6113         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6114         return WSError::WS_ERROR_INVALID_PERMISSION;
6115     }
6116     auto task = [this, &listener]() {
6117         WSError ret = WSError::WS_DO_NOTHING;
6118         if (listenerController_ != nullptr) {
6119             ret = listenerController_->AddSessionListener(listener);
6120         } else {
6121             WLOGFE("The listenerController is nullptr");
6122         }
6123 
6124         // app continue report for distributed scheduled service
6125         SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6126             static_cast<int32_t>(ret));
6127 
6128         return ret;
6129     };
6130     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6131 }
6132 
UnRegisterSessionListener(const sptr<ISessionListener> & listener)6133 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6134 {
6135     WLOGFI("Enter");
6136     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6137         WLOGFE("The caller is not system-app, can not use system-api");
6138         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6139     }
6140     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6141         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6142         return WSError::WS_ERROR_INVALID_PERMISSION;
6143     }
6144     auto task = [this, &listener]() {
6145         if (listenerController_ != nullptr) {
6146             listenerController_->DelSessionListener(listener);
6147             return WSError::WS_OK;
6148         } else {
6149             WLOGFE("The listenerController is nullptr");
6150             return WSError::WS_DO_NOTHING;
6151         }
6152     };
6153     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6154 }
6155 
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6156 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6157                                              std::vector<SessionInfoBean>& sessionInfos)
6158 {
6159     WLOGFI("Enter num max %{public}d", numMax);
6160     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6161         WLOGFE("The caller is not system-app, can not use system-api");
6162         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6163     }
6164     if (!SessionPermission::VerifySessionPermission()) {
6165         WLOGFE("The caller has not permission granted");
6166         return WSError::WS_ERROR_INVALID_PERMISSION;
6167     }
6168     auto task = [this, &deviceId, numMax, &sessionInfos]() {
6169         if (CheckIsRemote(deviceId)) {
6170             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6171             if (ret != ERR_OK) {
6172                 return WSError::WS_ERROR_INVALID_PARAM;
6173             } else {
6174                 return WSError::WS_OK;
6175             }
6176         }
6177         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6178         std::vector<sptr<SceneSession>> sceneSessionInfos;
6179         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6180         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6181             auto sceneSession = iter->second;
6182             if (sceneSession == nullptr) {
6183                 WLOGFE("session is nullptr");
6184                 continue;
6185             }
6186             auto sessionInfo = sceneSession->GetSessionInfo();
6187             if (sessionInfo.isSystem_) {
6188                 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
6189                 continue;
6190             }
6191             auto want = sessionInfo.want;
6192             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
6193                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6194                     sceneSession->GetPersistentId());
6195                 continue;
6196             }
6197             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
6198                 break;
6199             }
6200             WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
6201                 sessionInfo.bundleName_.c_str());
6202             sceneSessionInfos.emplace_back(sceneSession);
6203         }
6204         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
6205     };
6206     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
6207 }
6208 
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)6209 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
6210 {
6211     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
6212     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
6213         TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
6214         return WSError::WS_ERROR_INVALID_PERMISSION;
6215     }
6216     if (pid < 0) {
6217         return WSError::WS_ERROR_INVALID_PARAM;
6218     }
6219     auto task = [this, pid, &windowStates] {
6220         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6221         for (const auto& [_, sceneSession] : sceneSessionMap_) {
6222             if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
6223                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6224                 MainWindowState windowState;
6225                 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
6226                 windowState.isVisible_ = sceneSession->GetRSVisible();
6227                 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
6228                 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
6229                 windowStates.emplace_back(windowState);
6230             }
6231         }
6232         return WSError::WS_OK;
6233     };
6234     return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
6235 }
6236 
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6237 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
6238                                                std::vector<SessionInfoBean>& sessionInfos)
6239 {
6240     TLOGI(WmsLogTag::DEFAULT, "begin");
6241     int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
6242     if (result != ERR_OK) {
6243         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6244         return result;
6245     }
6246     return ERR_OK;
6247 }
6248 
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6249 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
6250                                             int32_t persistentId, SessionInfoBean& sessionInfo)
6251 {
6252     WLOGFI("id %{public}d", persistentId);
6253     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6254         WLOGFE("The caller is not system-app, can not use system-api");
6255         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6256     }
6257     if (!SessionPermission::VerifySessionPermission()) {
6258         WLOGFE("The caller has not permission granted");
6259         return WSError::WS_ERROR_INVALID_PERMISSION;
6260     }
6261     auto task = [this, &deviceId, persistentId, &sessionInfo]() {
6262         if (CheckIsRemote(deviceId)) {
6263             int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
6264             if (ret != ERR_OK) {
6265                 return WSError::WS_ERROR_INVALID_PARAM;
6266             } else {
6267                 return WSError::WS_OK;
6268             }
6269         }
6270         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6271         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6272         iter = sceneSessionMap_.find(persistentId);
6273         if (iter != sceneSessionMap_.end()) {
6274             auto sceneSession = iter->second;
6275             if (sceneSession == nullptr) {
6276                 WLOGFE("session: %{public}d is nullptr", persistentId);
6277                 return WSError::WS_ERROR_INVALID_PARAM;
6278             }
6279             auto sceneSessionInfo = sceneSession->GetSessionInfo();
6280             if (sceneSessionInfo.isSystem_) {
6281                 WLOGFD("sessionId: %{public}d  isSystemScene", persistentId);
6282                 return WSError::WS_ERROR_INVALID_PARAM;
6283             }
6284             auto want = sceneSessionInfo.want;
6285             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
6286                 want->GetElement().GetBundleName().empty()) {
6287                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6288                     persistentId);
6289                 return WSError::WS_ERROR_INTERNAL_ERROR;
6290             }
6291             WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
6292                 sceneSessionInfo.bundleName_.c_str());
6293             return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
6294         } else {
6295             WLOGFW("sessionId: %{public}d not found", persistentId);
6296             return WSError::WS_ERROR_INVALID_PARAM;
6297         }
6298     };
6299     return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
6300 }
6301 
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)6302 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
6303     SessionInfoBean& sessionInfo)
6304 {
6305     TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
6306         continueSessionId.c_str());
6307     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6308         TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
6309         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6310     }
6311     if (!SessionPermission::VerifySessionPermission()) {
6312         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
6313         return WSError::WS_ERROR_INVALID_PERMISSION;
6314     }
6315     auto task = [this, continueSessionId, &sessionInfo]() {
6316         WSError ret = WSError::WS_ERROR_INVALID_SESSION;
6317         {
6318             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6319             for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
6320                 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
6321                     ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
6322                     break;
6323                 }
6324             }
6325         }
6326 
6327         TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
6328         // app continue report for distributed scheduled service
6329         SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
6330             static_cast<int32_t>(ret));
6331         return ret;
6332     };
6333     return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
6334 }
6335 
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6336 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
6337                                               int32_t persistentId, SessionInfoBean& sessionInfo)
6338 {
6339     WLOGFI("GetRemoteSessionInfoFromDms begin");
6340     std::vector<SessionInfoBean> sessionVector;
6341     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
6342     if (result != ERR_OK) {
6343         return result;
6344     }
6345     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
6346         if (iter->id == persistentId) {
6347             sessionInfo = *iter;
6348             return ERR_OK;
6349         }
6350     }
6351     WLOGFW("missionId not found");
6352     return ERR_INVALID_VALUE;
6353 }
6354 
CheckIsRemote(const std::string & deviceId)6355 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
6356 {
6357     if (deviceId.empty()) {
6358         WLOGFI("CheckIsRemote: deviceId is empty.");
6359         return false;
6360     }
6361     std::string localDeviceId;
6362     if (!GetLocalDeviceId(localDeviceId)) {
6363         WLOGFE("CheckIsRemote: get local deviceId failed");
6364         return false;
6365     }
6366     if (localDeviceId == deviceId) {
6367         WLOGFI("CheckIsRemote: deviceId is local.");
6368         return false;
6369     }
6370     WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
6371     return true;
6372 }
6373 
GetLocalDeviceId(std::string & localDeviceId)6374 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
6375 {
6376     auto localNode = std::make_unique<NodeBasicInfo>();
6377     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
6378     if (errCode != ERR_OK) {
6379         WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
6380         return false;
6381     }
6382     if (localNode != nullptr) {
6383         localDeviceId = localNode->networkId;
6384         WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
6385         return true;
6386     }
6387     WLOGFE("localDeviceId null");
6388     return false;
6389 }
6390 
AnonymizeDeviceId(const std::string & deviceId)6391 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
6392 {
6393     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
6394         return EMPTY_DEVICE_ID;
6395     }
6396     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
6397     anonDeviceId.append("******");
6398     return anonDeviceId;
6399 }
6400 
DumpSessionAll(std::vector<std::string> & infos)6401 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
6402 {
6403     WLOGFI("Dump all session.");
6404     if (!SessionPermission::IsSystemCalling()) {
6405         WLOGFE("DumpSessionAll permission denied!");
6406         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6407     }
6408 
6409     auto task = [this, &infos]() {
6410         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6411         infos.push_back(dumpInfo);
6412         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6413         for (const auto &item : sceneSessionMap_) {
6414             auto& session = item.second;
6415             if (session) {
6416                 session->DumpSessionInfo(infos);
6417             }
6418         }
6419         return WSError::WS_OK;
6420     };
6421 
6422     return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
6423 }
6424 
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)6425 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
6426 {
6427     WLOGFI("Dump session with id %{public}d", persistentId);
6428     if (!SessionPermission::IsSystemCalling()) {
6429         WLOGFE("DumpSessionWithId permission denied!");
6430         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6431     }
6432 
6433     auto task = [this, persistentId, &infos]() {
6434         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6435         infos.push_back(dumpInfo);
6436         auto session = GetSceneSession(persistentId);
6437         if (session) {
6438             session->DumpSessionInfo(infos);
6439         } else {
6440             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
6441         }
6442         return WSError::WS_OK;
6443     };
6444 
6445     return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
6446 }
6447 
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6448 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
6449     const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6450 {
6451     if (bundleMgr_ == nullptr) {
6452         WLOGFE("bundleMgr_ is nullptr");
6453         return WSError::WS_ERROR_NULLPTR;
6454     }
6455     auto elementName = want.GetElement();
6456     int32_t ret{0};
6457     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6458         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6459         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6460         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6461         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6462         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6463     std::vector<AppExecFwk::BundleInfo> bundleInfos;
6464     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
6465         WLOGFD("want is empty queryAllAbilityInfos");
6466         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
6467         if (ret) {
6468             WLOGFE("Query all ability infos from BMS failed!");
6469             return WSError::WS_ERROR_INVALID_PARAM;
6470         }
6471     } else if (!elementName.GetBundleName().empty()) {
6472         AppExecFwk::BundleInfo bundleInfo;
6473         WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
6474         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
6475         if (ret) {
6476             WLOGFE("Query ability info from BMS failed!");
6477             return WSError::WS_ERROR_INVALID_PARAM;
6478         }
6479         bundleInfos.push_back(bundleInfo);
6480     } else {
6481         WLOGFE("invalid want:%{public}s", want.ToString().c_str());
6482         return WSError::WS_ERROR_INVALID_PARAM;
6483     }
6484     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6485 }
6486 
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6487 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
6488     const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6489 {
6490     if (bundleMgr_ == nullptr) {
6491         TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
6492         return WSError::WS_ERROR_NULLPTR;
6493     }
6494     if (bundleNames.empty()) {
6495         TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
6496         return WSError::WS_ERROR_INVALID_PARAM;
6497     }
6498     auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6499                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6500                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6501                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6502                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6503                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
6504     std::vector<AppExecFwk::BundleInfo> bundleInfos;
6505     auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
6506     if (ret) {
6507         TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
6508         return WSError::WS_ERROR_INVALID_PARAM;
6509     }
6510     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6511 }
6512 
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)6513 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
6514     const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
6515 {
6516     if (bundleMgr_ == nullptr) {
6517         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
6518         return WSError::WS_ERROR_NULLPTR;
6519     }
6520     auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6521         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6522         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6523         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6524         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6525         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6526     AppExecFwk::BundleInfo bundleInfo;
6527     if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
6528         TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
6529         return WSError::WS_ERROR_INVALID_PARAM;
6530     }
6531     auto& hapModulesList = bundleInfo.hapModuleInfos;
6532     if (hapModulesList.empty()) {
6533         TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
6534         return WSError::WS_ERROR_INVALID_PARAM;
6535     }
6536     auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
6537     for (auto& hapModule : hapModulesList) {
6538         auto& abilityInfoList = hapModule.abilityInfos;
6539         for (auto& abilityInfo : abilityInfoList) {
6540             if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
6541                 scbAbilityInfo.abilityInfo_ = abilityInfo;
6542                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6543                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6544                 return WSError::WS_OK;
6545             }
6546         }
6547     }
6548     TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
6549     return WSError::WS_ERROR_INVALID_PARAM;
6550 }
6551 
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)6552 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
6553     std::vector<SCBAbilityInfo>& scbAbilityInfos)
6554 {
6555     if (bundleInfos.empty()) {
6556         WLOGFE("bundleInfos is empty");
6557         return WSError::WS_ERROR_INVALID_PARAM;
6558     }
6559     for (auto& bundleInfo : bundleInfos) {
6560         auto& hapModulesList = bundleInfo.hapModuleInfos;
6561         auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
6562         if (hapModulesList.empty()) {
6563             WLOGFD("hapModulesList is empty");
6564             continue;
6565         }
6566         if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
6567             bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
6568             auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
6569                 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
6570             if (iter != hapModulesList.end()) {
6571                 SCBAbilityInfo scbAbilityInfo;
6572                 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
6573                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6574                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6575                 scbAbilityInfos.push_back(scbAbilityInfo);
6576                 continue;
6577             }
6578         }
6579         for (auto& hapModule : hapModulesList) {
6580             auto& abilityInfoList = hapModule.abilityInfos;
6581             for (auto& abilityInfo : abilityInfoList) {
6582                 SCBAbilityInfo scbAbilityInfo;
6583                 scbAbilityInfo.abilityInfo_ = abilityInfo;
6584                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6585                 scbAbilityInfos.push_back(scbAbilityInfo);
6586             }
6587         }
6588     }
6589     return WSError::WS_OK;
6590 }
6591 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)6592 WSError SceneSessionManager::TerminateSessionNew(
6593     const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
6594 {
6595     if (info == nullptr) {
6596         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
6597         return WSError::WS_ERROR_INVALID_PARAM;
6598     }
6599     TLOGI(WmsLogTag::WMS_LIFE,
6600         "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
6601         info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
6602     int32_t callingPid = IPCSkeleton::GetCallingPid();
6603     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
6604     auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
6605         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
6606         if (sceneSession == nullptr) {
6607             TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
6608             return WSError::WS_ERROR_INVALID_PARAM;
6609         }
6610         const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
6611         if (!pidCheck &&
6612             !SessionPermission::VerifyPermissionByCallerToken(callerToken,
6613                 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6614             TLOGE(WmsLogTag::WMS_LIFE,
6615                 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
6616                 sceneSession->GetCallingPid(), callingPid);
6617             return WSError::WS_ERROR_INVALID_PERMISSION;
6618         }
6619         WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
6620         return errCode;
6621     };
6622     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
6623 }
6624 
SetVmaCacheStatus(bool flag)6625 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
6626 {
6627     WLOGFI("flag: %{public}d", flag);
6628     RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
6629     return WSError::WS_OK;
6630 }
6631 
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)6632 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
6633                                                 SessionSnapshot& snapshot, bool isLowResolution)
6634 {
6635     WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
6636     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6637         WLOGFE("The caller is not system-app, can not use system-api");
6638         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6639     }
6640     if (!SessionPermission::VerifySessionPermission()) {
6641         WLOGFE("The caller has not permission granted");
6642         return WSError::WS_ERROR_INVALID_PERMISSION;
6643     }
6644     auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
6645         if (CheckIsRemote(deviceId)) {
6646             int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
6647             if (ret != ERR_OK) {
6648                 return WSError::WS_ERROR_INVALID_PARAM;
6649             } else {
6650                 return WSError::WS_OK;
6651             }
6652         }
6653         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6654         if (!sceneSession) {
6655             return WSError::WS_ERROR_INVALID_PARAM;
6656         }
6657         auto sessionInfo = sceneSession->GetSessionInfo();
6658         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6659             WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6660                    sceneSession->GetPersistentId());
6661         }
6662         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
6663         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
6664         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
6665         auto oriSnapshot = sceneSession->Snapshot();
6666         if (oriSnapshot != nullptr) {
6667             if (isLowResolution) {
6668                 OHOS::Media::InitializationOptions options;
6669                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
6670                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
6671                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap
6672                     = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
6673                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
6674             } else {
6675                 snapshot.snapshot = oriSnapshot;
6676             }
6677         }
6678         return WSError::WS_OK;
6679     };
6680     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
6681 }
6682 
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)6683 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
6684 {
6685     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
6686         TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
6687         return WMError::WM_ERROR_NOT_SYSTEM_APP;
6688     }
6689     auto task = [this, persistentId, &snapshot]() {
6690         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6691         if (!sceneSession) {
6692             TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
6693             return WMError::WM_ERROR_INVALID_PARAM;
6694         }
6695         auto sessionInfo = sceneSession->GetSessionInfo();
6696         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6697             TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6698                 sceneSession->GetPersistentId());
6699         }
6700         snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
6701         snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
6702         snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
6703         auto oriSnapshot = sceneSession->Snapshot();
6704         if (oriSnapshot != nullptr) {
6705             snapshot.snapshot = oriSnapshot;
6706             return WMError::WM_OK;
6707         }
6708         return WMError::WM_ERROR_NULLPTR;
6709     };
6710     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
6711 }
6712 
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)6713 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
6714 {
6715     if (!SessionPermission::IsSACalling()) {
6716         TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
6717         return WSError::WS_ERROR_INVALID_PERMISSION;
6718     }
6719     TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
6720     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6721     if (sceneSession == nullptr) {
6722         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
6723         return WSError::WS_ERROR_NULLPTR;
6724     }
6725     return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
6726 }
6727 
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)6728 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
6729                                                       AAFwk::MissionSnapshot& sessionSnapshot)
6730 {
6731     TLOGI(WmsLogTag::DEFAULT, "begin");
6732     int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
6733         sessionId, sessionSnapshot);
6734     if (result != ERR_OK) {
6735         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6736         return result;
6737     }
6738     return ERR_OK;
6739 }
6740 
GetCollaboratorByType(int32_t collaboratorType)6741 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
6742 {
6743     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
6744     std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
6745     auto iter = collaboratorMap_.find(collaboratorType);
6746     if (iter == collaboratorMap_.end()) {
6747         TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
6748         return collaborator;
6749     }
6750     collaborator = iter->second;
6751     if (collaborator == nullptr) {
6752         TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
6753     }
6754     return collaborator;
6755 }
6756 
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)6757 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
6758 {
6759     wptr<SceneSession> weakSceneSession(sceneSession);
6760     auto task = [this, weakSceneSession]() {
6761         auto scnSession = weakSceneSession.promote();
6762         if (scnSession == nullptr) {
6763             WLOGFE("session is nullptr");
6764             return WSError::WS_ERROR_NULLPTR;
6765         }
6766         auto persistentId = scnSession->GetPersistentId();
6767         if (!GetSceneSession(persistentId)) {
6768             WLOGFE("session is invalid with %{public}d", persistentId);
6769             return WSError::WS_ERROR_INVALID_SESSION;
6770         }
6771         auto sessionInfo = scnSession->GetSessionInfo();
6772         auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
6773         if (!abilitySessionInfo) {
6774             TLOGE(WmsLogTag::WMS_MAIN,
6775                 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
6776             return WSError::WS_ERROR_NULLPTR;
6777         }
6778         TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
6779             sessionInfo.callState_, persistentId);
6780         bool isColdStart = false;
6781         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
6782         if (isColdStart) {
6783             TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
6784                 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
6785             scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
6786             scnSession->ResetSessionConnectState();
6787         }
6788         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
6789         return WSError::WS_OK;
6790     };
6791     std::string taskName = "RequestSceneSessionByCall:PID:" +
6792         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
6793     taskScheduler_->PostAsyncTask(task, taskName);
6794     return WSError::WS_OK;
6795 }
6796 
StartAbilityBySpecified(const SessionInfo & sessionInfo)6797 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
6798 {
6799     auto task = [this, sessionInfo]() {
6800         WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
6801             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6802         AAFwk::Want want;
6803         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
6804         if (sessionInfo.want != nullptr) {
6805             want.SetParams(sessionInfo.want->GetParams());
6806         }
6807         AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
6808     };
6809 
6810     taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
6811 }
6812 
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)6813 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
6814 {
6815     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
6816     if (pid == -1) {
6817         TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
6818         return;
6819     }
6820     int32_t ret = HiSysEventWrite(
6821         HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
6822         "WINDOW_STATE_ERROR",
6823         HiviewDFX::HiSysEvent::EventType::FAULT,
6824         "PID", pid,
6825         "PERSISTENT_ID", persistentId);
6826     if (ret != 0) {
6827         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
6828     }
6829     auto task = [this, pid] {
6830         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6831         for (const auto& [_, sceneSession] : sceneSessionMap_) {
6832             if (!sceneSession || pid != sceneSession->GetCallingPid() ||
6833                 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6834                 continue;
6835             }
6836             auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6837             if (abilitySessionInfo) {
6838                 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
6839                     abilitySessionInfo->persistentId);
6840                 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
6841             }
6842         }
6843     };
6844     // delay 2000ms, wait for hidumper
6845     taskScheduler_->PostAsyncTask(task, __func__, 2000);
6846 }
6847 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)6848 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
6849 {
6850     if (!targetToken) {
6851         WLOGFE("Token is null, cannot find main window");
6852         return nullptr;
6853     }
6854 
6855     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6856     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
6857         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
6858             if (pair.second->IsTerminated()) {
6859                 return false;
6860             }
6861             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6862                 return pair.second->GetAbilityToken() == targetToken;
6863             }
6864             return false;
6865         });
6866     if (iter == sceneSessionMap_.end()) {
6867         WLOGFE("Cannot find session");
6868         return nullptr;
6869     }
6870     return iter->second;
6871 }
6872 
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)6873 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
6874 {
6875     if (!SessionPermission::IsSystemCalling()) {
6876         TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
6877         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6878     }
6879     if (targetToken == nullptr) {
6880         TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
6881         return WSError::WS_ERROR_NULLPTR;
6882     }
6883 
6884     auto task = [this, persistentId, targetToken]() {
6885         auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
6886         if (scnSession == nullptr) {
6887             TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
6888             return WSError::WS_ERROR_NULLPTR;
6889         }
6890         if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
6891             TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
6892             return WSError::WS_OK;
6893         }
6894         scnSession->dialogTargetToken_ = targetToken;
6895         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
6896         if (parentSession == nullptr) {
6897             scnSession->NotifyDestroy();
6898             return WSError::WS_ERROR_INVALID_PARAM;
6899         }
6900         scnSession->SetParentSession(parentSession);
6901         scnSession->SetParentPersistentId(parentSession->GetPersistentId());
6902         UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
6903         TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
6904             persistentId, parentSession->GetPersistentId());
6905         return WSError::WS_OK;
6906     };
6907     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
6908 }
6909 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)6910 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
6911     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
6912 {
6913     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
6914 }
6915 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)6916 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
6917     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
6918 {
6919     auto isSaCall = SessionPermission::IsSACalling();
6920     if (!isSaCall) {
6921         WLOGFE("The interface only support for sa call");
6922         return WMError::WM_ERROR_INVALID_PERMISSION;
6923     }
6924     auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
6925         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6926         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6927         for (auto missionId : missionIds) {
6928             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
6929             if (iter == sceneSessionMap_.end()) {
6930                 continue;
6931             }
6932             auto sceneSession = iter->second;
6933             if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
6934                 continue;
6935             }
6936             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
6937             if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
6938                 surfaceNodeIds.push_back(missionId);
6939                 continue;
6940             }
6941             if (sceneSession->GetLeashWinSurfaceNode()) {
6942                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
6943             }
6944         }
6945         return WMError::WM_OK;
6946     };
6947     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
6948 }
6949 
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)6950 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
6951     const sptr<IWindowManagerAgent>& windowManagerAgent)
6952 {
6953     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
6954         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
6955         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
6956         if (!SessionPermission::IsSystemCalling()) {
6957             WLOGFE("RegisterWindowManagerAgent permission denied!");
6958             return WMError::WM_ERROR_NOT_SYSTEM_APP;
6959         }
6960     } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
6961         if (!SessionPermission::IsSystemServiceCalling()) {
6962             return WMError::WM_ERROR_INVALID_PERMISSION;
6963         }
6964     }
6965     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
6966         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
6967         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
6968         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
6969         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
6970         if (!SessionPermission::IsSACalling()) {
6971             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
6972             return WMError::WM_ERROR_INVALID_PERMISSION;
6973         }
6974     }
6975     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
6976         WLOGFE("windowManagerAgent is null");
6977         return WMError::WM_ERROR_NULLPTR;
6978     }
6979     const auto callingPid = IPCSkeleton::GetCallingRealPid();
6980     auto task = [this, windowManagerAgent, type, callingPid]() {
6981         return SessionManagerAgentController::GetInstance()
6982             .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
6983     };
6984     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
6985 }
6986 
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)6987 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
6988     const sptr<IWindowManagerAgent>& windowManagerAgent)
6989 {
6990     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
6991         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
6992         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
6993         if (!SessionPermission::IsSystemCalling()) {
6994             WLOGFE("UnregisterWindowManagerAgent permission denied!");
6995             return WMError::WM_ERROR_NOT_SYSTEM_APP;
6996         }
6997     }
6998     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
6999         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7000         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7001         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7002         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7003         if (!SessionPermission::IsSACalling()) {
7004             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7005             return WMError::WM_ERROR_INVALID_PERMISSION;
7006         }
7007     }
7008     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7009         WLOGFE("windowManagerAgent is null");
7010         return WMError::WM_ERROR_NULLPTR;
7011     }
7012     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7013     auto task = [this, windowManagerAgent, type, callingPid]() {
7014         return SessionManagerAgentController::GetInstance()
7015             .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7016     };
7017     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7018 }
7019 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)7020 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7021 {
7022     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7023 }
7024 
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)7025 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7026 {
7027     SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7028 }
7029 
StartWindowInfoReportLoop()7030 void SceneSessionManager::StartWindowInfoReportLoop()
7031 {
7032     WLOGFD("Report loop");
7033     if (eventHandler_ == nullptr) {
7034         WLOGFE("Report event null");
7035         return ;
7036     }
7037     if (isReportTaskStart_) {
7038         WLOGFE("Report is ReportTask Start");
7039         return;
7040     }
7041     auto task = [this]() {
7042         WindowInfoReporter::GetInstance().ReportRecordedInfos();
7043         ReportWindowProfileInfos();
7044         isReportTaskStart_ = false;
7045         StartWindowInfoReportLoop();
7046     };
7047     int64_t delayTime = 1000 * 60 * 60; // an hour.
7048     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7049     if (!ret) {
7050         WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
7051         return;
7052     }
7053     isReportTaskStart_ = true;
7054 }
7055 
InitPersistentStorage()7056 void SceneSessionManager::InitPersistentStorage()
7057 {
7058     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7059         int32_t storageMode = -1;
7060         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7061         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7062             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7063             WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7064             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7065         }
7066     }
7067 }
7068 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)7069 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7070 {
7071     WLOGFD("Called.");
7072     if (!SessionPermission::IsSystemServiceCalling()) {
7073         WLOGFE("Only support for system service.");
7074         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7075     }
7076     auto task = [this, &infos]() {
7077         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7078         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7079         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7080             sptr<SceneSession> sceneSession = iter->second;
7081             if (sceneSession == nullptr) {
7082                 WLOGFW("null scene session");
7083                 continue;
7084             }
7085             bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7086                 sceneSession->IsVisibleForAccessibility() :
7087                 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7088             WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7089                 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7090                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7091                 sceneSession->GetSessionState(), isVisibleForAccessibility);
7092             if (isVisibleForAccessibility) {
7093                 FillWindowInfo(infos, iter->second);
7094             }
7095         }
7096         return WMError::WM_OK;
7097     };
7098     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7099 }
7100 
CheckUnreliableWindowType(WindowType windowType)7101 static bool CheckUnreliableWindowType(WindowType windowType)
7102 {
7103     if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7104         windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7105         windowType == WindowType::WINDOW_TYPE_TOAST) {
7106         return true;
7107     }
7108     TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7109     return false;
7110 }
7111 
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)7112 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7113     std::vector<sptr<UnreliableWindowInfo>>& infos)
7114 {
7115     if (sceneSession == nullptr) {
7116         TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7117         return;
7118     }
7119     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7120         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7121         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7122         TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7123         return;
7124     }
7125     sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo();
7126     if (info == nullptr) {
7127         TLOGE(WmsLogTag::DEFAULT, "null info.");
7128         return;
7129     }
7130     info->windowId_ = sceneSession->GetPersistentId();
7131     WSRect windowRect = sceneSession->GetSessionRect();
7132     info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7133     info->zOrder_ = sceneSession->GetZOrder();
7134     info->floatingScale_ = sceneSession->GetFloatingScale();
7135     info->scaleX_ = sceneSession->GetScaleX();
7136     info->scaleY_ = sceneSession->GetScaleY();
7137     infos.emplace_back(info);
7138     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7139 }
7140 
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)7141 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
7142     std::vector<sptr<UnreliableWindowInfo>>& infos)
7143 {
7144     TLOGD(WmsLogTag::DEFAULT, "Called.");
7145     if (!SessionPermission::IsSystemServiceCalling()) {
7146         TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
7147         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7148     }
7149     auto task = [this, windowId, &infos]() {
7150         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7151         for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
7152             if (sceneSession == nullptr) {
7153                 TLOGW(WmsLogTag::DEFAULT, "null scene session");
7154                 continue;
7155             }
7156             if (sessionId == windowId) {
7157                 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
7158                 FillUnreliableWindowInfo(sceneSession, infos);
7159                 continue;
7160             }
7161             if (!sceneSession->GetRSVisible()) {
7162                 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
7163                 continue;
7164             }
7165             TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
7166                 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
7167                 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
7168                 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
7169             if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
7170                 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
7171                     "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
7172                 FillUnreliableWindowInfo(sceneSession, infos);
7173             }
7174         }
7175         return WMError::WM_OK;
7176     };
7177     return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
7178 }
7179 
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)7180 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
7181 {
7182     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
7183     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7184     if (sceneSession == nullptr) {
7185         WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
7186         return;
7187     }
7188     wptr<SceneSession> weakSceneSession(sceneSession);
7189     if (processingFlushUIParams_.load()) {
7190         TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
7191         auto task = [this, weakSceneSession, type]() {
7192             auto sceneSession = weakSceneSession.promote();
7193             if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7194                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7195                 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7196             }
7197         };
7198         taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
7199         return;
7200     }
7201     auto task = [this, weakSceneSession, type]() {
7202         auto sceneSession = weakSceneSession.promote();
7203         NotifyAllAccessibilityInfo();
7204         if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7205             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7206             WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7207         }
7208     };
7209     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:id:" + std::to_string(persistentId));
7210 
7211     auto notifySceneInputTask = [weakSceneSession, type]() {
7212         auto sceneSession = weakSceneSession.promote();
7213         if (sceneSession == nullptr) {
7214             return;
7215         }
7216         SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
7217     };
7218     taskScheduler_->PostAsyncTask(notifySceneInputTask);
7219 }
7220 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)7221 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
7222     const sptr<SceneSession>& sceneSession)
7223 {
7224     if (sceneSession == nullptr) {
7225         WLOGFW("null scene session.");
7226         return false;
7227     }
7228     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7229         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7230         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7231         WLOGFD("filter gesture window.");
7232         return false;
7233     }
7234     sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
7235     if (info == nullptr) {
7236         WLOGFE("null info.");
7237         return false;
7238     }
7239     if (sceneSession->GetSessionInfo().isSystem_) {
7240         info->wid_ = 1;
7241         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7242     } else {
7243         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7244     }
7245     info->uiNodeId_ = sceneSession->GetUINodeId();
7246     WSRect wsrect = sceneSession->GetSessionGlobalRect(); // only accessability and mmi need global
7247     info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
7248     info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
7249     info->type_ = sceneSession->GetWindowType();
7250     info->mode_ = sceneSession->GetWindowMode();
7251     info->layer_ = sceneSession->GetZOrder();
7252     info->scaleVal_ = sceneSession->GetFloatingScale();
7253     info->scaleX_ = sceneSession->GetScaleX();
7254     info->scaleY_ = sceneSession->GetScaleY();
7255     info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
7256     info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
7257     auto property = sceneSession->GetSessionProperty();
7258     if (property != nullptr) {
7259         info->displayId_ = property->GetDisplayId();
7260         info->isDecorEnable_ = property->IsDecorEnable();
7261     }
7262     infos.emplace_back(info);
7263     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
7264         info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
7265     return true;
7266 }
7267 
GetSessionSnapshotFilePath(int32_t persistentId)7268 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
7269 {
7270     WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
7271     auto sceneSession = GetSceneSession(persistentId);
7272     if (sceneSession == nullptr) {
7273         WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
7274         return "";
7275     }
7276     wptr<SceneSession> weakSceneSession(sceneSession);
7277     auto task = [this, weakSceneSession]() {
7278         auto scnSession = weakSceneSession.promote();
7279         if (scnSession == nullptr) {
7280             WLOGFE("session is nullptr");
7281             return std::string("");
7282         }
7283         std::string filePath = scnSession->GetSessionSnapshotFilePath();
7284         return filePath;
7285     };
7286     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
7287 }
7288 
SelectSesssionFromMap(const uint64_t & surfaceId)7289 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
7290 {
7291     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7292     for (const auto &item : sceneSessionMap_) {
7293         auto sceneSession = item.second;
7294         if (sceneSession == nullptr) {
7295             continue;
7296         }
7297         if (sceneSession->GetSurfaceNode() == nullptr) {
7298             continue;
7299         }
7300         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
7301             return sceneSession;
7302         }
7303     }
7304     return nullptr;
7305 }
7306 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)7307 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
7308 {
7309     WLOGFD("WindowLayerInfoChangeCallback: entry");
7310     std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
7311 
7312     auto task = [this, weak]() {
7313         auto weakOcclusionData = weak.lock();
7314         if (weakOcclusionData == nullptr) {
7315             WLOGFE("weak occlusionData is nullptr");
7316             return;
7317         }
7318         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
7319         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
7320         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
7321         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
7322         if (currVisibleData.size() != 0) {
7323             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
7324         }
7325         if (visibilityChangeInfos.size() != 0) {
7326             DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
7327             CacVisibleWindowNum();
7328         }
7329 
7330         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
7331         if (currDrawingContentData.size() != 0) {
7332             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
7333         }
7334         if (drawingContentChangeInfos.size() != 0) {
7335             DealwithDrawingContentChange(drawingContentChangeInfos);
7336         }
7337     };
7338     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
7339 }
7340 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)7341 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
7342     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
7343     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
7344 {
7345     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
7346     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
7347         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
7348         switch (windowLayerState) {
7349             case WINDOW_ALL_VISIBLE:
7350             case WINDOW_SEMI_VISIBLE:
7351             case WINDOW_IN_VISIBLE:
7352                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
7353                 break;
7354             case WINDOW_LAYER_DRAWING:
7355                 currDrawingContentData.emplace_back(iter->first, true);
7356                 break;
7357             case WINDOW_LAYER_NO_DRAWING:
7358                 currDrawingContentData.emplace_back(iter->first, false);
7359                 break;
7360             default:
7361                 break;
7362         }
7363     }
7364 }
7365 
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)7366 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
7367     WindowVisibilityState visibleState,
7368     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7369     std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
7370     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7371 {
7372     if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
7373             visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7374         auto subSessions = GetSubSceneSession(session->GetWindowId());
7375         if (subSessions.empty()) {
7376             return;
7377         }
7378 
7379         RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
7380 
7381         for (const auto& subSession : subSessions) {
7382             if (subSession == nullptr) {
7383                 continue;
7384             }
7385             if (session->GetCallingPid() != subSession->GetCallingPid() &&
7386                 (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData))) {
7387                 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
7388                     subSession->GetWindowId());
7389                 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
7390             }
7391         }
7392     }
7393 }
7394 
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7395 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
7396     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7397 {
7398     bool sessionRSVisible = false;
7399     for (const auto& elem : currVisibleData) {
7400         uint64_t surfaceId = elem.first;
7401         WindowVisibilityState visibleState = elem.second;
7402         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7403         sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
7404         if (visibilitySession == nullptr) {
7405             continue;
7406         }
7407         if (session->GetWindowId() == visibilitySession->GetWindowId()) {
7408             if (isVisible) {
7409                 sessionRSVisible = true;
7410             }
7411             break;
7412         }
7413     }
7414     return sessionRSVisible;
7415 }
7416 
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)7417 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
7418     WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
7419     std::string& visibilityInfo)
7420 {
7421     if (session == nullptr) {
7422         TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
7423         return;
7424     }
7425     session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7426     session->SetVisibilityState(visibleState);
7427     int32_t windowId = session->GetWindowId();
7428     if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
7429         session->NotifyWindowVisibility();
7430     }
7431     windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
7432         windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
7433 
7434     visibilityInfo +=
7435         "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
7436 }
7437 
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)7438 void SceneSessionManager::RemoveDuplicateSubSession(
7439     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7440     std::vector<sptr<SceneSession>>& subSessions)
7441 {
7442     for (const auto& elem : visibilityChangeInfo) {
7443         uint64_t surfaceId = elem.first;
7444         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7445         if (session == nullptr) {
7446             continue;
7447         }
7448         for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
7449             auto subSession = *iterator;
7450             if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
7451                 iterator = subSessions.erase(iterator);
7452             } else {
7453                 ++iterator;
7454             }
7455         }
7456     }
7457 }
7458 
GetSubSceneSession(int32_t parentWindowId)7459 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
7460 {
7461     std::vector<sptr<SceneSession>> subSessions;
7462     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7463     for (const auto& iter : sceneSessionMap_) {
7464         auto sceneSession = iter.second;
7465         if (sceneSession == nullptr) {
7466             continue;
7467         }
7468         if (sceneSession->GetParentSession() != nullptr &&
7469             sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
7470             subSessions.push_back(sceneSession);
7471         }
7472     }
7473     return subSessions;
7474 }
7475 
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7476 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
7477     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7478 {
7479     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
7480     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
7481     uint32_t i, j;
7482     i = j = 0;
7483     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
7484         if (lastVisibleData_[i].first < currVisibleData[j].first) {
7485             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7486             i++;
7487         } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
7488             if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7489                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7490             }
7491             j++;
7492         } else {
7493             if (lastVisibleData_[i].second != currVisibleData[j].second) {
7494                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7495             }
7496             i++;
7497             j++;
7498         }
7499     }
7500     for (; i < lastVisibleData_.size(); ++i) {
7501         visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7502     }
7503     for (; j < currVisibleData.size(); ++j) {
7504         if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7505             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7506         }
7507     }
7508     lastVisibleData_ = currVisibleData;
7509     return visibilityChangeInfo;
7510 }
7511 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7512 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
7513     visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7514 {
7515     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7516 #ifdef MEMMGR_WINDOW_ENABLE
7517     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7518 #endif
7519 
7520     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
7521     for (const auto& elem : visibilityChangeInfo) {
7522         uint64_t surfaceId = elem.first;
7523         WindowVisibilityState visibleState = elem.second;
7524         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7525         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7526         if (session == nullptr) {
7527             continue;
7528         }
7529         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
7530             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
7531             if (session->GetParentSession() != nullptr &&
7532                 !session->GetParentSession()->IsSessionForeground() &&
7533                 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
7534                 continue;
7535             }
7536         }
7537         SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
7538         UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
7539 #ifdef MEMMGR_WINDOW_ENABLE
7540     memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
7541         session->GetCallingUid(), isVisible));
7542 #endif
7543         CheckAndNotifyWaterMarkChangedResult();
7544     }
7545     if (windowVisibilityInfos.size() != 0) {
7546         WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
7547             visibilityInfo.c_str());
7548         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7549     }
7550 #ifdef MEMMGR_WINDOW_ENABLE
7551     if (memMgrWindowInfos.size() != 0) {
7552         WLOGD("Notify memMgrWindowInfos changed start");
7553         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7554     }
7555 #endif
7556 }
7557 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)7558 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
7559     drawingContentChangeInfo)
7560 {
7561     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
7562     for (const auto& elem : drawingContentChangeInfo) {
7563         uint64_t surfaceId = elem.first;
7564         bool drawingState = elem.second;
7565         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7566         if (session == nullptr) {
7567             continue;
7568         }
7569         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
7570             session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
7571         if (openDebugTrace) {
7572             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
7573                 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
7574         }
7575         WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
7576             "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
7577     }
7578     if (windowDrawingContenInfos.size() != 0) {
7579         WLOGFD("Notify WindowDrawingContenInfo changed start");
7580         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
7581     }
7582 }
7583 
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)7584 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
7585     std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
7586 {
7587     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
7588     for (const auto& data : currDrawingContentData) {
7589         uint64_t windowId = data.first;
7590         bool currentDrawingContentState = data.second;
7591         int32_t pid = 0;
7592         bool isChange = false;
7593         if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
7594             continue;
7595         } else {
7596             isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
7597         }
7598         if (isChange) {
7599             processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
7600         }
7601     }
7602     return processDrawingContentChangeInfo;
7603 }
7604 
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)7605 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
7606 {
7607     bool preWindowDrawingState = true;
7608     sptr<SceneSession> session = SelectSesssionFromMap(windowId);
7609     if (session == nullptr) {
7610         return false;
7611     }
7612     pid = session->GetCallingPid();
7613     preWindowDrawingState = session->GetDrawingContentState();
7614     session->SetDrawingContentState(currentDrawingContentState);
7615     return preWindowDrawingState;
7616 }
7617 
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)7618 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
7619 {
7620     bool isChange = true;
7621     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7622     for (const auto& item : sceneSessionMap_) {
7623         auto sceneSession = item.second;
7624         if (sceneSession == nullptr) {
7625             continue;
7626         }
7627         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
7628             windowId != sceneSession->GetSurfaceNode()->GetId()) {
7629             if (sceneSession->GetDrawingContentState()) {
7630                 return false;
7631             }
7632         }
7633     }
7634     return isChange;
7635 }
7636 
InitWithRenderServiceAdded()7637 void SceneSessionManager::InitWithRenderServiceAdded()
7638 {
7639     auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
7640         this->WindowLayerInfoChangeCallback(occlusiontionData);
7641     };
7642     WLOGI("RegisterWindowVisibilityChangeCallback");
7643     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
7644         WLOGFE("RegisterWindowVisibilityChangeCallback failed");
7645     }
7646 }
7647 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)7648 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
7649 {
7650     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
7651         WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
7652         return WMError::WM_ERROR_INVALID_PARAM;
7653     }
7654 
7655     auto task = [this, sceneType]() {
7656         WLOGFD("Set system animated scene %{public}d.", sceneType);
7657         bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
7658         if (!ret) {
7659             WLOGFE("Set system animated scene failed.");
7660         }
7661     };
7662     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
7663     return WMError::WM_OK;
7664 }
7665 
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)7666 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
7667 {
7668     if (!SessionPermission::IsSystemCalling()) {
7669         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
7670         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7671     }
7672     if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
7673         TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
7674         return WSError::WS_ERROR_INVALID_PERMISSION;
7675     }
7676     TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
7677         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
7678     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7679     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
7680         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
7681 	WindowType::WINDOW_TYPE_APP_COMPONENT));
7682     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7683     return WSError::WS_OK;
7684 }
7685 
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)7686 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
7687 {
7688     if (sceneSession == nullptr) {
7689         WLOGFE("sceneSession is nullptr!");
7690         return;
7691     }
7692     if (sceneSession->GetRSVisible()) {
7693         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7694 #ifdef MEMMGR_WINDOW_ENABLE
7695         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7696 #endif
7697         sceneSession->SetRSVisible(false);
7698         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7699         sceneSession->ClearExtWindowFlags();
7700         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
7701             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
7702             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
7703 #ifdef MEMMGR_WINDOW_ENABLE
7704         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
7705             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
7706 #endif
7707         WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
7708             sceneSession->GetWindowId(), sceneSession->GetRSVisible());
7709         CheckAndNotifyWaterMarkChangedResult();
7710         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7711 #ifdef MEMMGR_WINDOW_ENABLE
7712         WLOGD("Notify memMgrWindowInfos changed start");
7713         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7714 #endif
7715     }
7716 }
7717 
FindSessionByToken(const sptr<IRemoteObject> & token)7718 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
7719 {
7720     if (token == nullptr) {
7721         TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
7722         return nullptr;
7723     }
7724     sptr<SceneSession> session = nullptr;
7725     auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7726         if (pair.second == nullptr) {
7727             return false;
7728         }
7729         return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
7730     };
7731     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7732     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7733     if (iter != sceneSessionMap_.end()) {
7734         session = iter->second;
7735     }
7736     return session;
7737 }
7738 
FindSessionByAffinity(std::string affinity)7739 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
7740 {
7741     if (affinity.size() == 0) {
7742         WLOGFI("AbilityInfo affinity is empty");
7743         return nullptr;
7744     }
7745     sptr<SceneSession> session = nullptr;
7746     auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7747         if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
7748             return false;
7749         }
7750         return pair.second->GetSessionInfo().sessionAffinity == affinity;
7751     };
7752     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7753     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7754     if (iter != sceneSessionMap_.end()) {
7755         session = iter->second;
7756     }
7757     return session;
7758 }
7759 
PreloadInLakeApp(const std::string & bundleName)7760 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
7761 {
7762     WLOGFD("Enter name %{public}s", bundleName.c_str());
7763     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
7764     if (collaborator != nullptr) {
7765         WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
7766         collaborator->NotifyPreloadAbility(bundleName);
7767     }
7768 }
7769 
PendingSessionToForeground(const sptr<IRemoteObject> & token)7770 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
7771 {
7772     TLOGI(WmsLogTag::DEFAULT, "Session is going to foreground");
7773     auto pid = IPCSkeleton::GetCallingRealPid();
7774     if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
7775         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
7776         return WSError::WS_ERROR_INVALID_PERMISSION;
7777     }
7778 
7779     auto task = [this, &token]() {
7780         auto session = FindSessionByToken(token);
7781         if (session != nullptr) {
7782             return session->PendingSessionToForeground();
7783         }
7784         TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
7785         return WSError::WS_ERROR_INVALID_PARAM;
7786     };
7787     return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
7788 }
7789 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)7790 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
7791     bool shouldBackToCaller)
7792 {
7793     auto task = [this, &token, shouldBackToCaller] {
7794         auto session = FindSessionByToken(token);
7795         if (session != nullptr) {
7796             return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
7797         }
7798         TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
7799         return WSError::WS_ERROR_INVALID_PARAM;
7800     };
7801     return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
7802 }
7803 
ClearDisplayStatusBarTemporarilyFlags()7804 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
7805 {
7806     for (auto persistentId : avoidAreaListenerSessionSet_) {
7807         auto sceneSession = GetSceneSession(persistentId);
7808         if (sceneSession == nullptr) {
7809             continue;
7810         }
7811         sceneSession->SetIsDisplayStatusBarTemporarily(false);
7812     }
7813 }
7814 
GetFocusSessionToken(sptr<IRemoteObject> & token)7815 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
7816 {
7817     if (!SessionPermission::IsSACalling()) {
7818         WLOGFE("GetFocusSessionToken permission denied!");
7819         return WSError::WS_ERROR_INVALID_PERMISSION;
7820     }
7821     auto task = [this, &token]() {
7822         WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
7823         auto sceneSession = GetSceneSession(focusedSessionId_);
7824         if (sceneSession) {
7825             token = sceneSession->GetAbilityToken();
7826             if (token == nullptr) {
7827                 WLOGFE("token is nullptr");
7828                 return WSError::WS_ERROR_INVALID_PARAM;
7829             }
7830             return WSError::WS_OK;
7831         }
7832         return WSError::WS_ERROR_INVALID_PARAM;
7833     };
7834     return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
7835 }
7836 
GetFocusSessionElement(AppExecFwk::ElementName & element)7837 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
7838 {
7839     AppExecFwk::RunningProcessInfo info;
7840     auto pid = IPCSkeleton::GetCallingRealPid();
7841     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
7842     if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
7843         WLOGFE("GetFocusSessionElement permission denied!");
7844         return WSError::WS_ERROR_INVALID_PERMISSION;
7845     }
7846     auto task = [this, &element]() {
7847         WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
7848         auto sceneSession = GetSceneSession(focusedSessionId_);
7849         if (sceneSession) {
7850             auto sessionInfo = sceneSession->GetSessionInfo();
7851             element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
7852                 sessionInfo.abilityName_, sessionInfo.moduleName_);
7853             return WSError::WS_OK;
7854         }
7855         return WSError::WS_ERROR_INVALID_SESSION;
7856     };
7857     return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
7858 }
7859 
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)7860 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
7861 {
7862     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7863     auto task = [this, persistentId, haveListener, callingPid]() {
7864         TLOGI(WmsLogTag::WMS_IMMS,
7865             "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
7866             persistentId, haveListener);
7867         auto sceneSession = GetSceneSession(persistentId);
7868         if (sceneSession == nullptr) {
7869             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
7870             return WSError::WS_DO_NOTHING;
7871         }
7872         if (callingPid != sceneSession->GetCallingPid()) {
7873             TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
7874             return WSError::WS_ERROR_INVALID_PERMISSION;
7875         }
7876         if (haveListener) {
7877             avoidAreaListenerSessionSet_.insert(persistentId);
7878             UpdateAvoidArea(persistentId);
7879         } else {
7880             lastUpdatedAvoidArea_.erase(persistentId);
7881             avoidAreaListenerSessionSet_.erase(persistentId);
7882         }
7883         return WSError::WS_OK;
7884     };
7885     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
7886 }
7887 
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const sptr<SceneSession> & sceneSession,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)7888 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
7889     const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
7890 {
7891     if (sceneSession == nullptr) {
7892         TLOGI(WmsLogTag::WMS_IMMS, "scene session null no need update avoid area");
7893         return false;
7894     }
7895     if (lastUpdatedAvoidArea_.find(persistentId) == lastUpdatedAvoidArea_.end()) {
7896         lastUpdatedAvoidArea_[persistentId] = {};
7897     }
7898 
7899     bool needUpdate = true;
7900     if (auto iter = lastUpdatedAvoidArea_[persistentId].find(avoidAreaType);
7901         iter != lastUpdatedAvoidArea_[persistentId].end()) {
7902         needUpdate = iter->second != avoidArea;
7903     } else {
7904         if (avoidArea.isEmptyAvoidArea()) {
7905             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}d type %{public}d empty avoid area",
7906                 persistentId, avoidAreaType);
7907             needUpdate = false;
7908             return needUpdate;
7909         }
7910     }
7911     if (needUpdate) {
7912         lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
7913         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
7914     }
7915 
7916     return needUpdate;
7917 }
7918 
UpdateAvoidSessionAvoidArea(WindowType type,bool & needUpdate)7919 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
7920 {
7921     bool ret = true;
7922     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
7923         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
7924     for (auto& persistentId : avoidAreaListenerSessionSet_) {
7925         auto sceneSession = GetSceneSession(persistentId);
7926         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
7927             continue;
7928         }
7929         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
7930         ret = UpdateSessionAvoidAreaIfNeed(
7931             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
7932         needUpdate = needUpdate || ret;
7933     }
7934 
7935     return;
7936 }
7937 
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)7938 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
7939 {
7940     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
7941         !avoidArea.rightRect_.IsUninitializedRect()) {
7942         return false;
7943     }
7944     if (avoidArea.bottomRect_.IsUninitializedRect()) {
7945         return true;
7946     }
7947     if (isVisible &&
7948         (avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) == sessionBottom)) {
7949         return true;
7950     }
7951     return false;
7952 }
7953 
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)7954 void SceneSessionManager::UpdateNormalSessionAvoidArea(
7955     const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
7956 {
7957     bool ret = true;
7958     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
7959         TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
7960             persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
7961         needUpdate = false;
7962         return;
7963     }
7964     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
7965         TLOGD(WmsLogTag::WMS_IMMS,
7966             "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
7967         needUpdate = false;
7968         return;
7969     }
7970     uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
7971     uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
7972     for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
7973         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
7974         if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
7975             !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
7976                 sceneSession->GetSessionRect().height_)) {
7977             continue;
7978         }
7979         ret = UpdateSessionAvoidAreaIfNeed(
7980             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
7981         needUpdate = needUpdate || ret;
7982     }
7983 
7984     return;
7985 }
7986 
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)7987 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
7988 {
7989     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
7990     auto sceneSession = GetSceneSession(windowId);
7991     if (sceneSession == nullptr) {
7992         WLOGFW("window not exist: %{public}d", windowId);
7993         return;
7994     }
7995 
7996     wptr<SceneSession> weakSceneSession(sceneSession);
7997     WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
7998     auto task = [weakSceneSession, startMoving]() -> WSError {
7999         auto scnSession = weakSceneSession.promote();
8000         if (scnSession == nullptr) {
8001             WLOGFW("session is null");
8002             return WSError::WS_ERROR_NULLPTR;
8003         }
8004         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8005         return WSError::WS_OK;
8006     };
8007     return taskScheduler_->PostAsyncTask(task);
8008 }
8009 
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)8010 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
8011     const std::string taskName, const int delayTime)
8012 {
8013     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
8014 }
8015 
UpdateAvoidArea(int32_t persistentId)8016 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8017 {
8018     auto task = [this, persistentId] {
8019         bool needUpdate = false;
8020         auto sceneSession = GetSceneSession(persistentId);
8021         if (sceneSession == nullptr) {
8022             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8023             return;
8024         }
8025         WindowType type = sceneSession->GetWindowType();
8026         if (sceneSession->IsImmersiveType()) {
8027             UpdateAvoidSessionAvoidArea(type, needUpdate);
8028         } else {
8029             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8030         }
8031         if (needUpdate) {
8032             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8033         }
8034         return;
8035     };
8036     taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8037     return;
8038 }
8039 
UpdateAvoidAreaByType(int32_t persistentId,AvoidAreaType type)8040 void SceneSessionManager::UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)
8041 {
8042     auto task = [this, persistentId, type] {
8043         auto sceneSession = GetSceneSession(persistentId);
8044         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8045             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is nullptr or invisible", persistentId);
8046             return;
8047         }
8048         if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8049             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d has no listener, no need update", persistentId);
8050             return;
8051         }
8052         if (sceneSession->IsImmersiveType()) {
8053             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is immersive type", persistentId);
8054             return;
8055         }
8056         auto avoidArea = sceneSession->GetAvoidAreaByType(type);
8057         if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && !CheckAvoidAreaForAINavigationBar(
8058             isAINavigationBarVisible_, avoidArea, sceneSession->GetSessionRect().height_)) {
8059             return;
8060         }
8061         UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, type);
8062     };
8063     taskScheduler_->PostAsyncTask(task, "UpdateAvoidAreaByType:PID:" + std::to_string(persistentId));
8064 }
8065 
UpdateGestureBackEnabled(int32_t persistentId)8066 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8067 {
8068     auto task = [this, persistentId] {
8069         auto sceneSession = GetSceneSession(persistentId);
8070         if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8071             TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8072             return;
8073         }
8074         auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8075         if (needEnableGestureBack) {
8076             gestureBackEnableWindowIdSet_.erase(persistentId);
8077         } else {
8078             gestureBackEnableWindowIdSet_.insert(persistentId);
8079         }
8080         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8081             sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8082             (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8083              sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8084             enterRecent_.load() || !sceneSession->IsFocused()) {
8085             needEnableGestureBack = true;
8086         }
8087         if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8088             gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8089                 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8090         } else {
8091             TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8092         }
8093     };
8094     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8095 }
8096 
UpdateOccupiedAreaIfNeed(const int32_t & persistentId)8097 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8098 {
8099     auto task = [this, persistentId]() {
8100         sptr<SceneSession> keyboardSession = nullptr;
8101         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8102         for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8103             auto sceneSession = item->second;
8104             if (sceneSession != nullptr &&
8105                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8106                 keyboardSession = sceneSession;
8107                 break;
8108             }
8109         }
8110         if (keyboardSession == nullptr) {
8111             TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8112             return;
8113         }
8114         if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8115             return;
8116         }
8117 
8118         keyboardSession->OnCallingSessionUpdated();
8119         return;
8120     };
8121     taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8122     return;
8123 }
8124 
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)8125 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8126 {
8127     TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8128         isVisible, persistentId);
8129     auto task = [this, persistentId, isVisible] {
8130         auto sceneSession = GetSceneSession(persistentId);
8131         if (sceneSession == nullptr) {
8132             TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8133             return;
8134         }
8135         sceneSession->SetIsStatusBarVisible(isVisible);
8136     };
8137     taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8138     return WSError::WS_OK;
8139 }
8140 
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)8141 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8142 {
8143     WLOGFI("isVisible: %{public}u, "
8144         "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8145         isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8146     auto task = [this, isVisible, barArea, displayId]() {
8147         bool isNeedNotify = isAINavigationBarVisible_ != isVisible;
8148         {
8149             std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8150             bool isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8151                 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8152                 currAINavigationBarAreaMap_[displayId] != barArea;
8153             if (isNeedUpdate) {
8154                 isAINavigationBarVisible_ = isVisible;
8155                 currAINavigationBarAreaMap_.clear();
8156                 currAINavigationBarAreaMap_[displayId] = barArea;
8157             }
8158             if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8159                 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8160                 currAINavigationBarAreaMap_[displayId] = WSRect();
8161             }
8162         }
8163         if (isNeedNotify) {
8164             WLOGFI("NotifyAINavigationBar: enter: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8165                 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8166             for (auto persistentId : avoidAreaListenerSessionSet_) {
8167                 NotifySessionAINavigationBarChange(persistentId);
8168             }
8169         }
8170     };
8171     taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
8172     return WSError::WS_OK;
8173 }
8174 
NotifySessionAINavigationBarChange(int32_t persistentId)8175 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
8176 {
8177     auto sceneSession = GetSceneSession(persistentId);
8178     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8179         return;
8180     }
8181     AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8182     if (!CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8183         sceneSession->GetSessionRect().height_)) {
8184         return;
8185     }
8186     WLOGFI("NotifyAINavigationBarShowStatus: persistentId: %{public}d, "
8187         "{%{public}d,%{public}d,%{public}d,%{public}d}", persistentId,
8188         avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
8189         avoidArea.bottomRect_.width_, avoidArea.bottomRect_.height_);
8190     UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
8191         AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8192 }
8193 
GetAINavigationBarArea(uint64_t displayId)8194 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
8195 {
8196     std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8197     if (currAINavigationBarAreaMap_.count(displayId) == 0) {
8198         return {};
8199     }
8200     return currAINavigationBarAreaMap_[displayId];
8201 }
8202 
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)8203 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
8204 {
8205     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8206     auto task = [this, persistentId, haveListener, callingPid]() {
8207         TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
8208             persistentId, haveListener);
8209         auto sceneSession = GetSceneSession(persistentId);
8210         if (sceneSession == nullptr) {
8211             TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
8212             return WSError::WS_DO_NOTHING;
8213         }
8214         if (callingPid != sceneSession->GetCallingPid()) {
8215             TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
8216             return WSError::WS_ERROR_INVALID_PERMISSION;
8217         }
8218         if (haveListener) {
8219             touchOutsideListenerSessionSet_.insert(persistentId);
8220         } else {
8221             touchOutsideListenerSessionSet_.erase(persistentId);
8222         }
8223         return WSError::WS_OK;
8224     };
8225     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
8226 }
8227 
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)8228 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
8229 {
8230     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
8231     auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
8232         WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
8233             persistentId, haveListener);
8234         auto sceneSession = GetSceneSession(persistentId);
8235         if (sceneSession == nullptr) {
8236             WLOGFD("sceneSession is nullptr.");
8237             return WSError::WS_DO_NOTHING;
8238         }
8239         if (callingPid != sceneSession->GetCallingPid()) {
8240             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
8241             return WSError::WS_ERROR_INVALID_PERMISSION;
8242         }
8243         if (haveListener) {
8244             windowVisibilityListenerSessionSet_.insert(persistentId);
8245             sceneSession->NotifyWindowVisibility();
8246         } else {
8247             windowVisibilityListenerSessionSet_.erase(persistentId);
8248         }
8249         return WSError::WS_OK;
8250     };
8251     return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
8252 }
8253 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)8254 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
8255 {
8256     processVirtualPixelRatioChangeFunc_ = func;
8257     WLOGFI("SetVirtualPixelRatioChangeListener");
8258 }
8259 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8260 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8261     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8262 {
8263     if (displayInfo == nullptr) {
8264         WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
8265         return;
8266     }
8267     auto task = [this, displayInfo]() {
8268         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8269         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
8270             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
8271             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
8272                 displayInfo->GetWidth(), displayInfo->GetHeight()
8273             };
8274             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
8275         }
8276         for (const auto &item : sceneSessionMap_) {
8277             auto scnSession = item.second;
8278             if (scnSession == nullptr) {
8279                 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
8280                 continue;
8281             }
8282             SessionInfo sessionInfo = scnSession->GetSessionInfo();
8283             if (sessionInfo.isSystem_) {
8284                 continue;
8285             }
8286             if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8287                 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
8288                 scnSession->UpdateDensity();
8289                 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
8290                     "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
8291                     scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8292             }
8293         }
8294         UpdateDisplayRegion(displayInfo);
8295         return WSError::WS_OK;
8296     };
8297     taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
8298 }
8299 
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8300 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8301     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8302 {
8303     if (displayInfo == nullptr) {
8304         WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
8305         return;
8306     }
8307     auto task = [this, displayInfo]() {
8308         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8309         for (const auto &item : sceneSessionMap_) {
8310             auto scnSession = item.second;
8311             if (scnSession == nullptr) {
8312                 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
8313                 continue;
8314             }
8315             if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8316                 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
8317                 continue;
8318             }
8319             if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
8320                 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
8321                 scnSession->GetRotation() != displayInfo->GetRotation()) {
8322                 scnSession->UpdateRotationAvoidArea();
8323                 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
8324                     "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
8325                     item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8326             }
8327             scnSession->SetRotation(displayInfo->GetRotation());
8328             scnSession->UpdateOrientation();
8329         }
8330         UpdateDisplayRegion(displayInfo);
8331         return WSError::WS_OK;
8332     };
8333     taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
8334 }
8335 
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)8336 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
8337 {
8338     if (displayInfo == nullptr) {
8339         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
8340         return;
8341     }
8342 
8343     auto task = [displayInfo]() -> WSError {
8344         ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
8345             displayInfo->GetScaleX(),
8346             displayInfo->GetScaleY(),
8347             displayInfo->GetPivotX(),
8348             displayInfo->GetPivotY(),
8349             displayInfo->GetTranslateX(),
8350             displayInfo->GetTranslateY());
8351         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
8352         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
8353         return WSError::WS_OK;
8354     };
8355     return taskScheduler_->PostAsyncTask(task);
8356 }
8357 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8358 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8359     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8360 {
8361     WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
8362     switch (type) {
8363         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
8364             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
8365                 displayInfo, displayInfoMap, type);
8366             break;
8367         }
8368         case DisplayStateChangeType::UPDATE_ROTATION: {
8369             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
8370                 displayInfo, displayInfoMap, type);
8371             break;
8372         }
8373         case DisplayStateChangeType::UPDATE_SCALE: {
8374             SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
8375             break;
8376         }
8377         default:
8378             return;
8379     }
8380 }
8381 
OnScreenshot(DisplayId displayId)8382 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
8383 {
8384     SceneSessionManager::GetInstance().OnScreenshot(displayId);
8385 }
8386 
OnScreenshot(DisplayId displayId)8387 void SceneSessionManager::OnScreenshot(DisplayId displayId)
8388 {
8389     auto task = [this, displayId]() {
8390         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8391         for (const auto& iter : sceneSessionMap_) {
8392             auto sceneSession = iter.second;
8393             if (sceneSession == nullptr) {
8394                 continue;
8395             }
8396             auto state = sceneSession->GetSessionState();
8397             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
8398                 sceneSession->NotifyScreenshot();
8399             }
8400         }
8401     };
8402     taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
8403 }
8404 
ClearSession(int32_t persistentId)8405 WSError SceneSessionManager::ClearSession(int32_t persistentId)
8406 {
8407     WLOGFI("id: %{public}d", persistentId);
8408     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8409         WLOGFE("The caller is not system-app, can not use system-api");
8410         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8411     }
8412     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8413         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8414         return WSError::WS_ERROR_INVALID_PERMISSION;
8415     }
8416     auto task = [this, persistentId]() {
8417         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8418         return ClearSession(sceneSession);
8419     };
8420     taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
8421     return WSError::WS_OK;
8422 }
8423 
ClearSession(sptr<SceneSession> sceneSession)8424 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
8425 {
8426     WLOGFD("Enter");
8427     if (sceneSession == nullptr) {
8428         WLOGFE("session is nullptr");
8429         return WSError::WS_ERROR_INVALID_SESSION;
8430     }
8431     if (!IsSessionClearable(sceneSession)) {
8432         WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
8433         return WSError::WS_ERROR_INVALID_SESSION;
8434     }
8435     const WSError errCode = sceneSession->Clear();
8436     return errCode;
8437 }
8438 
ClearAllSessions()8439 WSError SceneSessionManager::ClearAllSessions()
8440 {
8441     WLOGFD("Enter");
8442     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8443         WLOGFE("The caller is not system-app, can not use system-api");
8444         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8445     }
8446     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8447         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8448         return WSError::WS_ERROR_INVALID_PERMISSION;
8449     }
8450     auto task = [this]() {
8451         std::vector<sptr<SceneSession>> sessionVector;
8452         GetAllClearableSessions(sessionVector);
8453         for (uint32_t i = 0; i < sessionVector.size(); i++) {
8454             ClearSession(sessionVector[i]);
8455         }
8456         return WSError::WS_OK;
8457     };
8458     taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
8459     return WSError::WS_OK;
8460 }
8461 
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)8462 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
8463 {
8464     WLOGFD("Enter");
8465     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8466     for (const auto &item : sceneSessionMap_) {
8467         auto scnSession = item.second;
8468         if (IsSessionClearable(scnSession)) {
8469             sessionVector.push_back(scnSession);
8470         }
8471     }
8472 }
8473 
LockSession(int32_t sessionId)8474 WSError SceneSessionManager::LockSession(int32_t sessionId)
8475 {
8476     WLOGFI("id: %{public}d", sessionId);
8477     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8478         WLOGFE("The caller is not system-app, can not use system-api");
8479         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8480     }
8481     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8482         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8483         return WSError::WS_ERROR_INVALID_PERMISSION;
8484     }
8485     auto task = [this, sessionId]() {
8486         auto sceneSession = GetSceneSession(sessionId);
8487         if (sceneSession == nullptr) {
8488             WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
8489             return WSError::WS_ERROR_INVALID_PARAM;
8490         }
8491         sceneSession->SetSessionInfoLockedState(true);
8492         return WSError::WS_OK;
8493     };
8494     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
8495 }
8496 
UnlockSession(int32_t sessionId)8497 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
8498 {
8499     WLOGFI("id: %{public}d", sessionId);
8500     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8501         WLOGFE("The caller is not system-app, can not use system-api");
8502         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8503     }
8504     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8505         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8506         return WSError::WS_ERROR_INVALID_PERMISSION;
8507     }
8508     auto task = [this, sessionId]() {
8509         auto sceneSession = GetSceneSession(sessionId);
8510         if (sceneSession == nullptr) {
8511             WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
8512             return WSError::WS_ERROR_INVALID_PARAM;
8513         }
8514         sceneSession->SetSessionInfoLockedState(false);
8515         return WSError::WS_OK;
8516     };
8517     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
8518 }
8519 
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)8520 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
8521 {
8522     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8523     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8524         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8525         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8526     }
8527     if (!SessionPermission::VerifySessionPermission()) {
8528         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8529         return WSError::WS_ERROR_INVALID_PERMISSION;
8530     }
8531 
8532     return WSError::WS_OK;
8533 }
8534 
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)8535 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
8536     std::vector<int32_t>& result)
8537 {
8538     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8539     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8540         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8541         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8542     }
8543     if (!SessionPermission::VerifySessionPermission()) {
8544         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8545         return WSError::WS_ERROR_INVALID_PERMISSION;
8546     }
8547 
8548     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
8549     return WSError::WS_OK;
8550 }
8551 
IsSessionClearable(sptr<SceneSession> scnSession)8552 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
8553 {
8554     if (scnSession == nullptr) {
8555         WLOGFI("scnSession is nullptr");
8556         return false;
8557     }
8558     SessionInfo sessionInfo = scnSession->GetSessionInfo();
8559     if (sessionInfo.abilityInfo == nullptr) {
8560         WLOGFI("scnSession abilityInfo is nullptr");
8561         return false;
8562     }
8563     if (sessionInfo.abilityInfo->excludeFromMissions && !scnSession->IsAnco()) {
8564         WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
8565         return false;
8566     }
8567     if (sessionInfo.abilityInfo->unclearableMission) {
8568         WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
8569         return false;
8570     }
8571     if (sessionInfo.isSystem_) {
8572         WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
8573         return false;
8574     }
8575     if (sessionInfo.lockedState) {
8576         WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
8577         return false;
8578     }
8579 
8580     return true;
8581 }
8582 
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)8583 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
8584     const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
8585 {
8586     WLOGFI("type: %{public}d", type);
8587     auto isSaCall = SessionPermission::IsSACalling();
8588     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8589         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8590         return WSError::WS_ERROR_INVALID_PERMISSION;
8591     }
8592     if (!CheckCollaboratorType(type)) {
8593         WLOGFW("collaborator register failed, invalid type.");
8594         return WSError::WS_ERROR_INVALID_TYPE;
8595     }
8596     {
8597         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8598         collaboratorMap_[type] = impl;
8599     }
8600     auto task = [this] {
8601         if (abilityManagerCollaboratorRegisteredFunc_) {
8602             abilityManagerCollaboratorRegisteredFunc_();
8603         }
8604     };
8605     taskScheduler_->PostTask(task, __func__);
8606     return WSError::WS_OK;
8607 }
8608 
UnregisterIAbilityManagerCollaborator(int32_t type)8609 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
8610 {
8611     WLOGFI("type: %{public}d", type);
8612     auto isSaCall = SessionPermission::IsSACalling();
8613     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8614         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8615         return WSError::WS_ERROR_INVALID_PERMISSION;
8616     }
8617     if (!CheckCollaboratorType(type)) {
8618         WLOGFE("collaborator unregister failed, invalid type.");
8619         return WSError::WS_ERROR_INVALID_TYPE;
8620     }
8621     {
8622         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8623         collaboratorMap_.erase(type);
8624     }
8625     return WSError::WS_OK;
8626 }
8627 
CheckCollaboratorType(int32_t type)8628 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
8629 {
8630     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
8631         WLOGFD("type is invalid");
8632         return false;
8633     }
8634     return true;
8635 }
8636 
CheckIfReuseSession(SessionInfo & sessionInfo)8637 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
8638 {
8639     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
8640         sessionInfo.moduleName_);
8641     if (abilityInfo == nullptr) {
8642         WLOGFE("abilityInfo is nullptr!");
8643         return BrokerStates::BROKER_UNKOWN;
8644     }
8645     sessionInfo.abilityInfo = abilityInfo;
8646     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
8647     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
8648         collaboratorType = CollaboratorType::RESERVE_TYPE;
8649     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
8650         collaboratorType = CollaboratorType::OTHERS_TYPE;
8651     }
8652     if (!CheckCollaboratorType(collaboratorType)) {
8653         WLOGFW("checked not collaborator!");
8654         return BrokerStates::BROKER_UNKOWN;
8655     }
8656     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
8657     sessionInfo.collaboratorType_ = collaboratorType;
8658     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8659     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
8660         WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
8661         sessionInfo.reuse = true;
8662     } else {
8663         sessionInfo.reuse = false;
8664     }
8665     WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
8666         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
8667     return resultValue;
8668 }
8669 
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)8670 BrokerStates SceneSessionManager::NotifyStartAbility(
8671     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
8672 {
8673     WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
8674     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8675     if (collaborator == nullptr) {
8676         return BrokerStates::BROKER_UNKOWN;
8677     }
8678     if (sessionInfo.want == nullptr) {
8679         WLOGFI("sessionInfo.want is nullptr, init");
8680         sessionInfo.want = std::make_shared<AAFwk::Want>();
8681         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
8682             sessionInfo.moduleName_);
8683     }
8684     auto accessTokenIDEx = sessionInfo.callingTokenId_;
8685     if (collaborator != nullptr) {
8686         containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
8687             std::chrono::system_clock::now().time_since_epoch()).count();
8688 
8689         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8690         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
8691             WLOGFI("want affinity exit %{public}s.", affinity.c_str());
8692             return BrokerStates::BROKER_UNKOWN;
8693         }
8694         sessionInfo.want->SetParam("oh_persistentId", persistentId);
8695         int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
8696             currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
8697         WLOGFI("collaborator ret: %{public}d", ret);
8698         if (ret == 0) {
8699             return BrokerStates::BROKER_STARTED;
8700         } else {
8701             return BrokerStates::BROKER_NOT_START;
8702         }
8703     }
8704     return BrokerStates::BROKER_UNKOWN;
8705 }
8706 
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)8707 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
8708 {
8709     if (sceneSession == nullptr) {
8710         WLOGFE("sceneSession is nullptr");
8711         return;
8712     }
8713     if (sessionInfo.want == nullptr) {
8714         WLOGFI("sessionInfo.want is nullptr");
8715         return;
8716     }
8717     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8718     if (collaborator == nullptr) {
8719         return;
8720     }
8721     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8722     if (abilitySessionInfo == nullptr) {
8723         WLOGFE("abilitySessionInfo is nullptr");
8724         return;
8725     }
8726     abilitySessionInfo->want = *(sessionInfo.want);
8727     if (collaborator != nullptr) {
8728         int32_t missionId = abilitySessionInfo->persistentId;
8729         std::string bundleName = sessionInfo.bundleName_;
8730         int64_t timestamp = containerStartAbilityTime_;
8731         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
8732         WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
8733             missionId, bundleName.c_str());
8734         collaborator->NotifyMissionCreated(abilitySessionInfo);
8735     }
8736 }
8737 
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)8738 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
8739     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
8740 {
8741     WLOGFD("type: %{public}d", collaboratorType);
8742     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8743     if (collaborator != nullptr) {
8744         WLOGFI("called NotifyLoadAbility");
8745         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
8746     }
8747 }
8748 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)8749 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
8750 {
8751     WLOGFD("Enter");
8752     if (sceneSession == nullptr) {
8753         WLOGFE("sceneSession is nullptr");
8754         return;
8755     }
8756     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8757     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8758     if (collaborator != nullptr) {
8759         WLOGFI("called UpdateMissionInfo");
8760         collaborator->UpdateMissionInfo(abilitySessionInfo);
8761     }
8762 }
8763 
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)8764 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
8765 {
8766     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8767     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8768     if (collaborator != nullptr) {
8769         WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
8770         collaborator->NotifyMoveMissionToForeground(persistentId);
8771     }
8772 }
8773 
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)8774 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
8775 {
8776     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8777     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8778     if (collaborator != nullptr) {
8779         WLOGFI("called NotifyClearMission %{public}d", persistentId);
8780         collaborator->NotifyClearMission(persistentId);
8781     }
8782 }
8783 
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)8784 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
8785 {
8786     if (sceneSession == nullptr) {
8787         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
8788         return false;
8789     }
8790     std::string sessionAffinity;
8791     TLOGI(WmsLogTag::WMS_LIFE, "call");
8792     if (sceneSession->GetSessionInfo().want != nullptr) {
8793         sessionAffinity = sceneSession->GetSessionInfo().want
8794             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8795     }
8796     if (sessionAffinity.empty()) {
8797         TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
8798         BrokerStates notifyReturn = NotifyStartAbility(
8799             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
8800         if (notifyReturn == BrokerStates::BROKER_NOT_START) {
8801             TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
8802             return false;
8803         }
8804     }
8805     if (sceneSession->GetSessionInfo().want != nullptr) {
8806         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
8807             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
8808         TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
8809             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
8810             sceneSession->GetSessionInfo().sessionAffinity.c_str());
8811     } else {
8812         TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
8813     }
8814     return true;
8815 }
8816 
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)8817 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
8818 {
8819     if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
8820         return false;
8821     }
8822     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
8823     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
8824     return true;
8825 }
8826 
AddWindowDragHotArea(uint32_t type,WSRect & area)8827 void SceneSessionManager::AddWindowDragHotArea(uint32_t type, WSRect& area)
8828 {
8829     WLOGFI("type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
8830         "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
8831     SceneSession::AddOrUpdateWindowDragHotArea(type, area);
8832 }
8833 
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)8834 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
8835 {
8836     auto task = [this, persistentId, isMaximize]() -> WSError {
8837         WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
8838         auto sceneSession = GetSceneSession(persistentId);
8839         if (sceneSession == nullptr) {
8840             WLOGFE("could not find window, persistentId:%{public}d", persistentId);
8841             return WSError::WS_ERROR_INVALID_WINDOW;
8842         }
8843         sceneSession->UpdateMaximizeMode(isMaximize);
8844         return WSError::WS_OK;
8845     };
8846     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
8847     return WSError::WS_OK;
8848 }
8849 
GetIsLayoutFullScreen(bool & isLayoutFullScreen)8850 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
8851 {
8852     auto task = [this, &isLayoutFullScreen]() {
8853         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8854         for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
8855             auto sceneSession = item->second;
8856             if (sceneSession == nullptr) {
8857                 WLOGFE("Session is nullptr");
8858                 continue;
8859             }
8860             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
8861                 continue;
8862             }
8863             auto state = sceneSession->GetSessionState();
8864             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8865                 continue;
8866             }
8867             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
8868                 continue;
8869             }
8870             auto property = sceneSession->GetSessionProperty();
8871             if (property == nullptr) {
8872                 WLOGFE("Property is nullptr");
8873                 continue;
8874             }
8875             isLayoutFullScreen = property->IsLayoutFullScreen();
8876             auto persistentId = sceneSession->GetPersistentId();
8877             if (isLayoutFullScreen) {
8878                 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
8879                 return WSError::WS_OK;
8880             } else {
8881                 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
8882             }
8883         }
8884         WLOGFD("No immersive window");
8885         return WSError::WS_OK;
8886     };
8887 
8888     taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
8889     return WSError::WS_OK;
8890 }
8891 
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)8892 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
8893 {
8894     auto scnSession = GetSceneSession(persistentId);
8895     if (!scnSession) {
8896         WLOGFE("session is nullptr");
8897         return WSError::WS_ERROR_INVALID_WINDOW;
8898     }
8899     auto fromScreenId = scnSession->GetSessionInfo().screenId_;
8900     scnSession->SetScreenId(screenId);
8901     auto sessionProperty = scnSession->GetSessionProperty();
8902     if (!sessionProperty) {
8903         WLOGFE("Property is null, synchronous screenId failed");
8904         return WSError::WS_ERROR_NULLPTR;
8905     }
8906     sessionProperty->SetDisplayId(screenId);
8907     WLOGFD("Session move display %{public}" PRIu64 " from %{public}" PRIu64, screenId, fromScreenId);
8908     NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
8909     scnSession->NotifyDisplayMove(fromScreenId, screenId);
8910     scnSession->UpdateDensity();
8911     return WSError::WS_OK;
8912 }
8913 
NotifyStackEmpty(int32_t persistentId)8914 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
8915 {
8916     TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
8917     auto task = [this, persistentId]() {
8918         auto scnSession = GetSceneSession(persistentId);
8919         if (!scnSession) {
8920             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
8921             return WSError::WS_ERROR_INVALID_WINDOW;
8922         }
8923         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
8924         return WSError::WS_OK;
8925     };
8926     taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
8927     return WSError::WS_OK;
8928 }
8929 
OnImmersiveStateChange(bool & immersive)8930 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
8931 {
8932     immersive = SceneSessionManager::GetInstance().GetImmersiveState();
8933 }
8934 
GetImmersiveState()8935 bool SceneSessionManager::GetImmersiveState()
8936 {
8937     auto task = [this] {
8938         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8939         for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
8940             auto sceneSession = item->second;
8941             if (sceneSession == nullptr) {
8942                 WLOGFE("Session is nullptr");
8943                 continue;
8944             }
8945             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
8946                 continue;
8947             }
8948             auto state = sceneSession->GetSessionState();
8949             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8950                 continue;
8951             }
8952             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
8953                 continue;
8954             }
8955             auto property = sceneSession->GetSessionProperty();
8956             if (property == nullptr) {
8957                 WLOGFE("Property is nullptr");
8958                 continue;
8959             }
8960             auto sysBarProperty = property->GetSystemBarProperty();
8961             if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
8962                 WLOGI("GetImmersiveState, window is immersive. id:%{public}d", sceneSession->GetPersistentId());
8963                 return true;
8964             } else {
8965                 WLOGI("GetImmersiveState, statusBar is enabled. id:%{public}d", sceneSession->GetPersistentId());
8966                 break;
8967             }
8968         }
8969         WLOGI("GetImmersiveState, not immersive");
8970         return false;
8971     };
8972     return taskScheduler_->PostSyncTask(task, "GetImmersiveState");
8973 }
8974 
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)8975 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
8976     bool withAnimation)
8977 {
8978     session->NotifySessionForeground(reason, withAnimation);
8979 }
8980 
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)8981 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
8982     bool withAnimation, bool isFromInnerkits)
8983 {
8984     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
8985 }
8986 
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)8987 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
8988 {
8989     auto sceneSession = GetSceneSession(persistentId);
8990     if (sceneSession == nullptr) {
8991         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
8992         return WSError::WS_ERROR_INVALID_WINDOW;
8993     }
8994     return sceneSession->UpdateTitleInTargetPos(isShow, height);
8995 }
8996 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)8997 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
8998 {
8999     WLOGFI("AppAnrListener OnAppDebugStarted");
9000     if (debugInfos.empty()) {
9001         WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9002         return;
9003     }
9004     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
9005 }
9006 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9007 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9008 {
9009     WLOGFI("AppAnrListener OnAppDebugStoped");
9010     if (debugInfos.empty()) {
9011         WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9012         return;
9013     }
9014     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
9015 }
9016 
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)9017 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9018 {
9019     if (!Session::IsScbCoreEnabled()) {
9020         return;
9021     }
9022     if (onFlushUIParamsFunc_ != nullptr) {
9023         onFlushUIParamsFunc_();
9024     }
9025     auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9026         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9027         TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9028         {
9029             std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9030             nextFlushCompletedCV_.notify_all();
9031         }
9032         std::vector<uint32_t> startingAppZOrderList;
9033         processingFlushUIParams_.store(true);
9034         {
9035             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9036             for (const auto& item : sceneSessionMap_) {
9037                 auto sceneSession = item.second;
9038                 if (sceneSession == nullptr) {
9039                     continue;
9040                 }
9041                 if (sceneSession->GetSessionInfo().screenId_ != SCREEN_ID_INVALID &&
9042                     sceneSession->GetSessionInfo().screenId_ != screenId) {
9043                     continue;
9044                 }
9045                 auto iter = uiParams.find(sceneSession->GetPersistentId());
9046                 if (iter != uiParams.end()) {
9047                     if (sceneSession->GetSessionInfo().screenId_ == SCREEN_ID_INVALID) {
9048                         sceneSession->SetScreenIdOnServer(screenId);
9049                     }
9050                     if ((systemConfig_.uiType_ == UI_TYPE_PHONE ||
9051                          (systemConfig_.uiType_ == UI_TYPE_PAD && !systemConfig_.IsFreeMultiWindowMode())) &&
9052                         sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
9053                         startingAppZOrderList.push_back(iter->second.zOrder_);
9054                         sceneSession->SetStartingBeforeVisible(false);
9055                     }
9056                     sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9057                 } else {
9058                     sessionMapDirty_ |= sceneSession->UpdateUIParam();
9059                 }
9060             }
9061         }
9062         processingFlushUIParams_.store(false);
9063 
9064         // post process if dirty
9065         if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9066             static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9067             TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9068             for (const auto& item : uiParams) {
9069                 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f"
9070                     " transY:%{public}f, needSync:%{public}d, intreactive:%{public}d", item.first, item.second.zOrder_,
9071                     item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
9072                     item.second.needSync_, item.second.interactive_);
9073             }
9074             ProcessUpdateLastFocusedAppId(startingAppZOrderList);
9075             ProcessFocusZOrderChange(sessionMapDirty_);
9076             PostProcessFocus();
9077             PostProcessProperty(sessionMapDirty_);
9078             NotifyAllAccessibilityInfo();
9079             AnomalyDetection::SceneZOrderCheckProcess();
9080         } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9081             PostProcessProperty(sessionMapDirty_);
9082         }
9083         FlushWindowInfoToMMI();
9084         sessionMapDirty_ = 0;
9085         {
9086             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9087             for (const auto& item : sceneSessionMap_) {
9088                 auto sceneSession = item.second;
9089                 if (sceneSession == nullptr) {
9090                     continue;
9091                 }
9092                 sceneSession->ResetSizeChangeReasonIfDirty();
9093                 sceneSession->ResetDirtyFlags();
9094                 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9095                     sceneSession->SetUIStateDirty(false);
9096                 }
9097             }
9098         }
9099     };
9100     taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9101 }
9102 
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)9103 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
9104 {
9105     TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu", lastFocusedAppSessionId_,
9106           zOrderList.size());
9107     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || zOrderList.empty()) {
9108         return;
9109     }
9110     auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId_);
9111     if (lastFocusedAppSession == nullptr) {
9112         return;
9113     }
9114     uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
9115     auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
9116         return zOrder > lastFocusedAppZOrder;
9117     });
9118     if (it != zOrderList.end()) {
9119         TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
9120         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
9121     }
9122 }
9123 
ProcessFocusZOrderChange(uint32_t dirty)9124 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
9125 {
9126     if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9127         return;
9128     }
9129     if (systemConfig_.uiType_ != UI_TYPE_PHONE && systemConfig_.uiType_ != UI_TYPE_PAD) {
9130         return;
9131     }
9132     TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9133     auto focusedSession = GetSceneSession(focusedSessionId_);
9134     // only when it's from a high zOrder to a low zOrder
9135     if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9136         focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9137         return;
9138     }
9139     auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9140     if (voiceInteractionSession == nullptr) {
9141         return;
9142     }
9143     TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9144           "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9145           voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9146     if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9147         focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9148         return;
9149     }
9150     RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9151 }
9152 
PostProcessFocus()9153 void SceneSessionManager::PostProcessFocus()
9154 {
9155     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9156     // priority process focus requests from top to bottom
9157     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9158     {
9159         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9160         for (auto& iter : sceneSessionMap_) {
9161             auto session = iter.second;
9162             if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9163                 continue;
9164             }
9165             processingSessions.push_back(iter);
9166         }
9167     }
9168     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
9169         bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
9170             !rhs.second->GetPostProcessFocusState().isFocused_;
9171         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
9172         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
9173         return focusCmp || lhsZOrder > rhsZOrder;
9174     };
9175     std::sort(processingSessions.begin(), processingSessions.end(), cmp);
9176 
9177     // only change focus one time
9178     bool focusChanged = false;
9179     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9180         auto session = iter->second;
9181         if (session == nullptr) {
9182             WLOGFE("session is nullptr");
9183             continue;
9184         }
9185         TLOGD(WmsLogTag::WMS_PIPELINE,
9186             "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
9187             session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
9188             session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
9189         if (focusChanged) {
9190             session->ResetPostProcessFocusState();
9191             continue;
9192         }
9193         WSError ret = WSError::WS_DO_NOTHING;
9194         if (session->GetPostProcessFocusState().isFocused_) {
9195             if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
9196                 ret = RequestSessionFocusImmediately(session->GetPersistentId());
9197             } else {
9198                 ret = RequestSessionFocus(session->GetPersistentId(), true,
9199                                           session->GetPostProcessFocusState().reason_);
9200             }
9201         } else {
9202             ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
9203         }
9204         session->ResetPostProcessFocusState();
9205         // if succeed then end process
9206         if (ret == WSError::WS_OK) {
9207             focusChanged = true;
9208         }
9209     }
9210 }
9211 
PostProcessProperty(uint32_t dirty)9212 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
9213 {
9214     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
9215     if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9216         // only trigger update avoid area
9217         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9218         for (auto& iter : sceneSessionMap_) {
9219             auto session = iter.second;
9220             if (session == nullptr) {
9221                 continue;
9222             }
9223             session->PostProcessNotifyAvoidArea();
9224         }
9225         return;
9226     }
9227 
9228     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9229     {
9230         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9231         for (auto& iter : sceneSessionMap_) {
9232             auto session = iter.second;
9233             if (session == nullptr || !session->GetPostProcessProperty()) {
9234                 continue;
9235             }
9236             processingSessions.push_back(iter);
9237         }
9238     }
9239 
9240     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9241         auto session = iter->second;
9242         if (session == nullptr) {
9243             WLOGFE("session is nullptr");
9244             continue;
9245         }
9246         TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
9247         UpdateForceHideState(session, session->GetSessionProperty(), true);
9248         HandleKeepScreenOn(session, session->IsKeepScreenOn());
9249         UpdatePrivateStateAndNotify(session->GetPersistentId());
9250         if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9251             ProcessSubSessionForeground(session);
9252         }
9253         session->SetPostProcessProperty(false);
9254     }
9255 
9256     // update avoid area
9257     {
9258         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9259         for (auto& iter : sceneSessionMap_) {
9260             auto session = iter.second;
9261             if (session == nullptr) {
9262                 continue;
9263             }
9264             session->PostProcessNotifyAvoidArea();
9265         }
9266     }
9267 }
9268 
9269 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)9270 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
9271 {
9272     WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
9273     auto isSaCall = SessionPermission::IsSACalling();
9274     if (!isSaCall) {
9275         WLOGFE("The interface only support for sa call");
9276         return WSError::WS_ERROR_INVALID_PERMISSION;
9277     }
9278     auto task = [this, persistentId]() {
9279         auto sceneSession = GetSceneSession(persistentId);
9280         if (sceneSession == nullptr) {
9281             WLOGFE("session is nullptr");
9282             return WSError::WS_ERROR_INVALID_SESSION;
9283         }
9284         if (!IsSessionVisibleForeground(sceneSession)) {
9285             WLOGFD("session is not visible!");
9286             return WSError::WS_DO_NOTHING;
9287         }
9288         FocusChangeReason reason = FocusChangeReason::MOVE_UP;
9289         RequestSessionFocus(persistentId, true, reason);
9290         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
9291             sceneSession->RaiseToAppTop();
9292         }
9293         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
9294             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
9295             WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
9296             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9297         }
9298         if (sceneSession == nullptr) {
9299             WLOGFE("parent session is nullptr");
9300             return WSError::WS_ERROR_INVALID_SESSION;
9301         }
9302         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9303             sceneSession->NotifyClick();
9304             return WSError::WS_OK;
9305         } else {
9306             WLOGFE("session is not app main window!");
9307             return WSError::WS_ERROR_INVALID_SESSION;
9308         }
9309     };
9310     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
9311     return WSError::WS_OK;
9312 }
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)9313 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
9314 {
9315     WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
9316     if (sourcePersistentId != focusedSessionId_) {
9317         WLOGFE("source session need be focused");
9318         return WSError::WS_ERROR_INVALID_OPERATION;
9319     }
9320     if (targetPersistentId == focusedSessionId_) {
9321         WLOGFE("target session has been focused");
9322         return WSError::WS_DO_NOTHING;
9323     }
9324     sptr<SceneSession> sourceSession = nullptr;
9325     WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
9326     if (ret != WSError::WS_OK) {
9327         return ret;
9328     }
9329     sptr<SceneSession> targetSession = nullptr;
9330     ret = GetAppMainSceneSession(targetSession, targetPersistentId);
9331     if (ret != WSError::WS_OK) {
9332         return ret;
9333     }
9334     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
9335         WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
9336             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
9337         return WSError::WS_ERROR_INVALID_CALLING;
9338     }
9339     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
9340         return WSError::WS_ERROR_INVALID_CALLING;
9341     }
9342     int32_t callingPid = IPCSkeleton::GetCallingPid();
9343     if (callingPid != targetSession->GetCallingPid()) {
9344         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
9345         return WSError::WS_ERROR_INVALID_CALLING;
9346     }
9347     targetSession->NotifyClick();
9348     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
9349     return RequestSessionFocus(targetPersistentId, false, reason);
9350 }
9351 
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)9352 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
9353 {
9354     sceneSession = GetSceneSession(persistentId);
9355     if (sceneSession == nullptr) {
9356         WLOGFE("session(%{public}d) is nullptr", persistentId);
9357         return WSError::WS_ERROR_INVALID_SESSION;
9358     }
9359     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9360         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
9361             WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
9362             return WSError::WS_ERROR_INVALID_CALLING;
9363         }
9364         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9365         if (sceneSession == nullptr) {
9366             WLOGFE("session(%{public}d) parent is nullptr", persistentId);
9367             return WSError::WS_ERROR_INVALID_SESSION;
9368         }
9369     }
9370     return WSError::WS_OK;
9371 }
9372 
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)9373 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
9374     const float scaleParam)
9375 {
9376     auto sceneSession = GetSceneSession(persistentId);
9377     if (!sceneSession) {
9378         WLOGFE("get scene session is nullptr");
9379         return nullptr;
9380     }
9381 
9382     wptr<SceneSession> weakSceneSession(sceneSession);
9383     auto task = [this, persistentId, scaleParam, weakSceneSession]() {
9384         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
9385         auto scnSession = weakSceneSession.promote();
9386         std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
9387         if (scnSession == nullptr) {
9388             WLOGFE("session is nullptr");
9389             return pixelMap;
9390         }
9391 
9392         if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
9393             scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
9394             pixelMap = scnSession->Snapshot(false, scaleParam);
9395         }
9396         if (!pixelMap) {
9397             WLOGFI("get local snapshot pixelmap start");
9398             pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
9399         }
9400         return pixelMap;
9401     };
9402     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
9403 }
9404 
GetSceneSessionMap()9405 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
9406 {
9407     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
9408     {
9409         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9410         retSceneSessionMap = sceneSessionMap_;
9411     }
9412     EraseIf(retSceneSessionMap, [this](const auto& pair) {
9413         if (pair.second == nullptr) {
9414             return true;
9415         }
9416 
9417         if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
9418             if (pair.second->IsVisible()) {
9419                 return false;
9420             }
9421             return true;
9422         }
9423 
9424         if (pair.second->IsSystemInput()) {
9425             return false;
9426         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
9427             return false;
9428         }
9429 
9430         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
9431             return true;
9432         }
9433         return false;
9434     });
9435     return retSceneSessionMap;
9436 }
9437 
NotifyUpdateRectAfterLayout()9438 void SceneSessionManager::NotifyUpdateRectAfterLayout()
9439 {
9440     auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
9441     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
9442     if (transactionController) {
9443         rsTransaction = transactionController->GetRSTransaction();
9444     }
9445     auto task = [this, rsTransaction]() {
9446         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9447         for (auto& iter: sceneSessionMap_) {
9448             auto sceneSession = iter.second;
9449             if (sceneSession && sceneSession->IsDirtyWindow()) {
9450                 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
9451             }
9452         }
9453     };
9454     // need sync task since animation transcation need
9455     return taskScheduler_->PostAsyncTask(task);
9456 }
9457 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)9458 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
9459 {
9460     if (!SessionPermission::IsSystemCalling()) {
9461         WLOGFE("GetVisibilityWindowInfo permission denied!");
9462         return WMError::WM_ERROR_NOT_SYSTEM_APP;
9463     }
9464     auto task = [this, &infos]() {
9465         for (auto [surfaceId, _] : lastVisibleData_) {
9466             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9467             if (session == nullptr) {
9468                 continue;
9469             }
9470             WSRect hostRect = session->GetSessionRect();
9471             Rect rect = {hostRect.posX_, hostRect.posY_,
9472                          static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
9473             auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
9474                                                 session->GetSessionProperty());
9475             infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
9476                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
9477                 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_));
9478         }
9479         return WMError::WM_OK;
9480     };
9481     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
9482 }
9483 
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)9484 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
9485 {
9486     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9487     for (const auto& [id, session] : sceneSessionMap_) {
9488         if (session == nullptr) {
9489             continue;
9490         }
9491         uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
9492         windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
9493     }
9494 }
9495 
FlushWindowInfoToMMI(const bool forceFlush)9496 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
9497 {
9498     auto task = [this, forceFlush] {
9499         if (isUserBackground_) {
9500             TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
9501             return;
9502         }
9503         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
9504         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
9505     };
9506     taskScheduler_->PostAsyncTask(task);
9507 }
9508 
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)9509 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
9510     int32_t& parentId)
9511 {
9512     // This function should be called in task
9513     auto iter = extSessionInfoMap_.find(token);
9514     if (iter == extSessionInfoMap_.end()) {
9515         return false;
9516     }
9517     persistentId = iter->second.persistentId;
9518     parentId = iter->second.parentId;
9519     return true;
9520 }
9521 
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession)9522 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)
9523 {
9524     auto task = [this, remoteExtSession]() {
9525         auto iter = remoteExtSessionMap_.find(remoteExtSession);
9526         if (iter == remoteExtSessionMap_.end()) {
9527             TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
9528             return;
9529         }
9530         int32_t persistentId = INVALID_SESSION_ID;
9531         int32_t parentId = INVALID_SESSION_ID;
9532         if (!GetExtensionWindowIds(iter->second, persistentId, parentId)) {
9533             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9534             return;
9535         }
9536 
9537         TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
9538             persistentId, parentId);
9539         auto sceneSession = GetSceneSession(parentId);
9540         if (sceneSession != nullptr) {
9541             auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
9542             sceneSession->RemoveExtWindowFlags(persistentId);
9543             if (oldFlags.hideNonSecureWindowsFlag) {
9544                 HandleSecureSessionShouldHide(sceneSession);
9545             }
9546             if (oldFlags.waterMarkFlag) {
9547                 CheckAndNotifyWaterMarkChangedResult();
9548             }
9549             if (oldFlags.privacyModeFlag) {
9550                 UpdatePrivateStateAndNotify(parentId);
9551             }
9552             sceneSession->RemoveModalUIExtension(persistentId);
9553             sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
9554         } else {
9555             ExtensionWindowFlags actions;
9556             actions.SetAllActive();
9557             HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
9558         }
9559         extSessionInfoMap_.erase(iter->second);
9560         remoteExtSessionMap_.erase(iter);
9561     };
9562     taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
9563 }
9564 
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)9565 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
9566 {
9567     auto pid = IPCSkeleton::GetCallingRealPid();
9568     auto task = [this, token, pid, rect]() {
9569         int32_t persistentId = INVALID_SESSION_ID;
9570         int32_t parentId = INVALID_SESSION_ID;
9571         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9572             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9573             return;
9574         }
9575         TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
9576             "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
9577             pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
9578         auto parentSession = GetSceneSession(parentId);
9579         if (parentSession) {
9580             auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
9581             auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
9582             Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
9583             ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect };
9584             TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
9585                 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
9586                 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
9587                 parentSession->GetSessionGlobalRect().ToString().c_str());
9588             parentSession->UpdateModalUIExtension(extensionInfo);
9589         }
9590     };
9591     taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
9592 }
9593 
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)9594 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
9595 {
9596     auto pid = IPCSkeleton::GetCallingRealPid();
9597     auto task = [this, token, pid, posX, posY]() {
9598         int32_t persistentId = INVALID_SESSION_ID;
9599         int32_t parentId = INVALID_SESSION_ID;
9600         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9601             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9602             return;
9603         }
9604         TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
9605             "parentId=%{public}d", pid, persistentId, parentId);
9606         auto parentSession = GetSceneSession(parentId);
9607         if (parentSession && parentSession->HasModalUIExtension()) {
9608             auto modalUIExtension = parentSession->GetLastModalUIExtensionEventInfo();
9609             if ((modalUIExtension.pid == pid) && (modalUIExtension.persistentId == persistentId)) {
9610                 parentSession->ProcessPointDownSession(posX, posY);
9611             }
9612         }
9613     };
9614     taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
9615 }
9616 
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId)9617 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
9618     const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)
9619 {
9620     auto pid = IPCSkeleton::GetCallingRealPid();
9621     auto task = [this, sessionStage, token, surfaceNodeId, pid]() {
9622         if (sessionStage == nullptr || token == nullptr) {
9623             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9624             return;
9625         }
9626         auto remoteExtSession = sessionStage->AsObject();
9627         if (remoteExtSession == nullptr) {
9628             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9629             return;
9630         }
9631         if (extensionDeath_ == nullptr) {
9632             TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
9633             return;
9634         }
9635         if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
9636             TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
9637             return;
9638         }
9639 
9640         AAFwk::UIExtensionSessionInfo info;
9641         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
9642         if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
9643             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
9644             return;
9645         }
9646 
9647         int32_t persistentId = info.persistentId;
9648         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
9649         UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
9650         TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
9651             "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
9652             surfaceNodeId, pid);
9653 
9654         remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
9655         extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
9656 
9657         auto parentSession = GetSceneSession(parentId);
9658         if (parentSession) {
9659             parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
9660         }
9661         if (usage == UIExtensionUsage::MODAL && parentSession) {
9662             ExtensionWindowEventInfo extensionInfo {
9663                 .persistentId = persistentId,
9664                 .pid = pid,
9665             };
9666             parentSession->AddModalUIExtension(extensionInfo);
9667         }
9668     };
9669     taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
9670 }
9671 
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token)9672 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
9673     const sptr<IRemoteObject>& token)
9674 {
9675     TLOGI(WmsLogTag::WMS_UIEXT, "called");
9676     auto task = [this, sessionStage, token]() {
9677         if (sessionStage == nullptr || token == nullptr) {
9678             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9679             return;
9680         }
9681         auto remoteExtSession = sessionStage->AsObject();
9682         if (remoteExtSession == nullptr) {
9683             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9684             return;
9685         }
9686         auto iter = remoteExtSessionMap_.find(remoteExtSession);
9687         if (iter->second != token) {
9688             TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
9689             return;
9690         }
9691 
9692         DestroyExtensionSession(remoteExtSession);
9693     };
9694     taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
9695 }
9696 
CalculateCombinedExtWindowFlags()9697 void SceneSessionManager::CalculateCombinedExtWindowFlags()
9698 {
9699     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
9700     combinedExtWindowFlags_.bitData = 0;
9701     for (const auto& iter: extWindowFlagsMap_) {
9702         combinedExtWindowFlags_.bitData |= iter.second.bitData;
9703     }
9704     specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
9705 }
9706 
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)9707 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
9708     ExtensionWindowFlags actions)
9709 {
9710     auto iter = extWindowFlagsMap_.find(persistentId);
9711     // Each flag is false when inactive, 0 means all flags are inactive
9712     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
9713     ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
9714     if (newFlags.bitData == 0) {
9715         extWindowFlagsMap_.erase(persistentId);
9716     } else {
9717         extWindowFlagsMap_[persistentId] = newFlags;
9718     }
9719     CalculateCombinedExtWindowFlags();
9720 }
9721 
HideNonSecureFloatingWindows()9722 void SceneSessionManager::HideNonSecureFloatingWindows()
9723 {
9724     bool shouldHide = false;
9725     {
9726         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9727         for (const auto& iter: sceneSessionMap_) {
9728             auto& session = iter.second;
9729             if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
9730                 shouldHide = true;
9731                 break;
9732             }
9733         }
9734     }
9735     if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
9736         TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
9737         shouldHide = true;
9738     }
9739     if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
9740         return;
9741     }
9742 
9743     shouldHideNonSecureFloatingWindows_.store(shouldHide);
9744     for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
9745         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
9746             session->NotifyForceHideChange(shouldHide);
9747             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9748                 session->GetWindowName().c_str(), persistentId, shouldHide);
9749         }
9750     }
9751 }
9752 
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)9753 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
9754 {
9755     // don't let sub-window show when switching secure host window to background
9756     if (!sceneSession->IsSessionForeground()) {
9757         return;
9758     }
9759 
9760     auto parentId = sceneSession->GetPersistentId();
9761     bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
9762     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9763     for (const auto& [persistentId, session] : sceneSessionMap_) {
9764         if (!session) {
9765             continue;
9766         }
9767         auto property = session->GetSessionProperty();
9768         if (!property || property->GetParentPersistentId() != parentId) {
9769             continue;
9770         }
9771 
9772         if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
9773             session->NotifyForceHideChange(shouldHide);
9774             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9775                 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
9776         }
9777     }
9778 }
9779 
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)9780 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
9781 {
9782     if (sceneSession == nullptr) {
9783         TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
9784         return WSError::WS_ERROR_INVALID_SESSION;
9785     }
9786 
9787     HideNonSecureFloatingWindows();
9788     HideNonSecureSubWindows(sceneSession);
9789     return WSError::WS_OK;
9790 }
9791 
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)9792 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
9793     ExtensionWindowFlags actions)
9794 {
9795     UpdateSpecialExtWindowFlags(persistentId, flags, actions);
9796     if (actions.waterMarkFlag) {
9797         CheckAndNotifyWaterMarkChangedResult();
9798     }
9799     if (actions.hideNonSecureWindowsFlag) {
9800         HideNonSecureFloatingWindows();
9801     }
9802     if (actions.privacyModeFlag) {
9803         UpdatePrivateStateAndNotifyForAllScreens();
9804     }
9805 }
9806 
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)9807 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
9808 {
9809     TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
9810     if (!SessionPermission::IsSystemCalling()) {
9811         TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
9812         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9813     }
9814     const auto callingPid = IPCSkeleton::GetCallingRealPid();
9815     auto task = [this, persistentId, shouldHide, callingPid]() {
9816         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9817         auto iter = sceneSessionMap_.find(persistentId);
9818         if (iter == sceneSessionMap_.end()) {
9819             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
9820                 persistentId);
9821             return WSError::WS_ERROR_INVALID_SESSION;
9822         }
9823         auto sceneSession = iter->second;
9824         if (sceneSession == nullptr) {
9825             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
9826             return WSError::WS_ERROR_NULLPTR;
9827         }
9828         if (callingPid != sceneSession->GetCallingPid()) {
9829             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
9830             return WSError::WS_ERROR_INVALID_PERMISSION;
9831         }
9832         sceneSession->SetShouldHideNonSecureWindows(shouldHide);
9833         return HandleSecureSessionShouldHide(sceneSession);
9834     };
9835 
9836     taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
9837     return WSError::WS_OK;
9838 }
9839 
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const9840 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
9841 {
9842     auto ret = WSError::WS_OK;
9843     bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
9844     if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
9845         actions.hideNonSecureWindowsFlag = false;
9846         actions.waterMarkFlag = false;
9847         TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
9848         ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
9849     }
9850     auto needPrivacyWindow = actions.privacyModeFlag;
9851     if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
9852         actions.privacyModeFlag = false;
9853         TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
9854         ret = WSError::WS_ERROR_INVALID_PERMISSION;
9855     }
9856     return ret;
9857 }
9858 
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)9859 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
9860     uint32_t extWindowActions)
9861 {
9862     ExtensionWindowFlags actions(extWindowActions);
9863     auto ret = CheckExtWindowFlagsPermission(actions);
9864     if (actions.bitData == 0) {
9865         return ret;
9866     }
9867 
9868     ExtensionWindowFlags flags(extWindowFlags);
9869     auto task = [this, token, flags, actions]() {
9870         int32_t persistentId = INVALID_SESSION_ID;
9871         int32_t parentId = INVALID_SESSION_ID;
9872         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9873             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9874             return WSError::WS_ERROR_INVALID_OPERATION;
9875         }
9876 
9877         TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
9878             "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
9879         auto sceneSession = GetSceneSession(parentId);
9880         if (sceneSession == nullptr) {
9881             TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
9882                 parentId);
9883             HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
9884             return WSError::WS_OK;
9885         }
9886 
9887         auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
9888         sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
9889         auto newFlags = sceneSession->GetCombinedExtWindowFlags();
9890         if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
9891             HandleSecureSessionShouldHide(sceneSession);
9892         }
9893         if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
9894             CheckAndNotifyWaterMarkChangedResult();
9895         }
9896         if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
9897             UpdatePrivateStateAndNotify(parentId);
9898         }
9899         return WSError::WS_OK;
9900     };
9901 
9902     taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
9903     return ret;
9904 }
9905 
GetHostWindowRect(int32_t hostWindowId,Rect & rect)9906 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
9907 {
9908     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
9909     if (!SessionPermission::IsSystemCalling()) {
9910         TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
9911         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9912     }
9913     auto task = [this, hostWindowId, &rect]() {
9914         auto sceneSession = GetSceneSession(hostWindowId);
9915         if (sceneSession == nullptr) {
9916             TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
9917             return WSError::WS_ERROR_INVALID_SESSION;
9918         }
9919         WSRect hostRect = sceneSession->GetSessionRect();
9920         rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
9921         return WSError::WS_OK;
9922     };
9923     taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
9924     return WSError::WS_OK;
9925 }
9926 
ReclaimPurgeableCleanMem()9927 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
9928 {
9929 #ifdef MEMMGR_WINDOW_ENABLE
9930     return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
9931 #else
9932     return -1;
9933 #endif
9934 }
9935 
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)9936 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
9937     const std::vector<VisibleWindowNumInfo>& currentInfo)
9938 {
9939     if (lastInfo.size() != currentInfo.size()) {
9940         WLOGFE("last and current info is not Same");
9941         return false;
9942     }
9943     int sizeOfLastInfo = static_cast<int>(lastInfo.size());
9944     for (int i = 0; i < sizeOfLastInfo; i++) {
9945         if (lastInfo[i].displayId != currentInfo[i].displayId ||
9946             lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
9947             WLOGFE("last and current visible window num is not Same");
9948             return false;
9949         }
9950     }
9951     return true;
9952 }
9953 
CacVisibleWindowNum()9954 void SceneSessionManager::CacVisibleWindowNum()
9955 {
9956     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
9957     {
9958         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9959         sceneSessionMapCopy = sceneSessionMap_;
9960     }
9961     std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
9962     bool isFullScreen = true;
9963     for (const auto& elem : sceneSessionMapCopy) {
9964         auto curSession = elem.second;
9965         if (curSession == nullptr) {
9966             continue;
9967         }
9968         bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
9969             curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
9970         if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
9971             continue;
9972         }
9973 
9974         bool isWindowVisible = curSession->GetRSVisible();
9975         if (isWindowVisible) {
9976             auto windowMode = curSession->GetWindowMode();
9977             if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
9978                 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
9979                 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
9980                 isFullScreen = false;
9981             }
9982             int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
9983             auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
9984                 [=](const VisibleWindowNumInfo& info) {
9985                     return (static_cast<int32_t>(info.displayId)) == displayId;
9986             });
9987             if (it == visibleWindowNumInfo.end()) {
9988                 visibleWindowNumInfo.push_back({displayId, 1});
9989             } else {
9990                 it->visibleWindowNum++;
9991             }
9992         }
9993     }
9994     if (isFullScreen) {
9995         std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
9996                       [](auto& info) { info.visibleWindowNum = 1; });
9997     }
9998     std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
9999     if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10000         SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10001         lastInfo_ = visibleWindowNumInfo;
10002     }
10003 }
10004 
ReportWindowProfileInfos()10005 void SceneSessionManager::ReportWindowProfileInfos()
10006 {
10007     enum class WindowVisibleState : int32_t {
10008         FOCUSBLE = 0,
10009         VISIBLE,
10010         MINIMIZED,
10011         OCCLUSION
10012     };
10013     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10014     {
10015         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10016         sceneSessionMapCopy = sceneSessionMap_;
10017     }
10018     auto focusWindowId = GetFocusedSessionId();
10019     for (const auto& elem : sceneSessionMapCopy) {
10020         auto curSession = elem.second;
10021         if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10022             curSession->GetWindowType() !=  WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10023             continue;
10024         }
10025         WindowProfileInfo windowProfileInfo;
10026         windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10027         windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10028             curSession->GetSessionProperty()->GetDisplayId());
10029         windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10030         if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10031             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10032         } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10033             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10034         } else if (!curSession->GetRSVisible()) {
10035             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10036         } else {
10037             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10038         }
10039         WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10040         WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10041             "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10042             windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10043             windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10044     }
10045 }
10046 
GetCustomDecorHeight(int32_t persistentId)10047 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10048 {
10049     int32_t height = 0;
10050     auto sceneSession = GetSceneSession(persistentId);
10051     if (sceneSession == nullptr) {
10052         TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10053         return 0;
10054     }
10055     height = sceneSession->GetCustomDecorHeight();
10056     TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10057     return height;
10058 }
10059 
removeFailRecoveredSession()10060 void SceneSessionManager::removeFailRecoveredSession()
10061 {
10062     for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10063         auto sceneSession = GetSceneSession(persistentId);
10064         if (sceneSession == nullptr) {
10065             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10066             continue;
10067         }
10068         if (!sceneSession->IsRecovered()) {
10069             TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10070             continue;
10071         }
10072         const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10073         if (!scnSessionInfo) {
10074             TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr,persistentId = %{public}d", persistentId);
10075             continue;
10076         }
10077         TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10078         sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10079     }
10080     failRecoveredPersistentIdSet_.clear();
10081 }
10082 
GetDisplayRegion(DisplayId displayId)10083 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10084 {
10085     if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10086         return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10087     }
10088     TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10089     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10090     if (display == nullptr) {
10091         TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10092         return nullptr;
10093     }
10094     auto displayInfo = display->GetDisplayInfo();
10095     if (displayInfo == nullptr) {
10096         TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
10097         return nullptr;
10098     }
10099     int32_t displayWidth = displayInfo->GetWidth();
10100     int32_t displayHeight = displayInfo->GetHeight();
10101     if (displayWidth == 0 || displayHeight == 0) {
10102         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10103         return nullptr;
10104     }
10105 
10106     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10107     auto region = std::make_shared<SkRegion>(rect);
10108     displayRegionMap_[displayId] = region;
10109     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10110     return std::make_shared<SkRegion>(rect);
10111 }
10112 
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)10113 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
10114 {
10115     if (displayInfo == nullptr) {
10116         TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
10117         return;
10118     }
10119     auto displayId = displayInfo->GetDisplayId();
10120     int32_t displayWidth = displayInfo->GetWidth();
10121     int32_t displayHeight = displayInfo->GetHeight();
10122     if (displayWidth == 0 || displayHeight == 0) {
10123         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10124         return;
10125     }
10126     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10127     auto region = std::make_shared<SkRegion>(rect);
10128     displayRegionMap_[displayId] = region;
10129     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10130 }
10131 
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)10132 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
10133 {
10134     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10135     for (const auto& item : sceneSessionMap_) {
10136         auto sceneSession = item.second;
10137         if (sceneSession == nullptr) {
10138             continue;
10139         }
10140         if (Session::IsScbCoreEnabled()) {
10141             if (!sceneSession->IsVisibleForAccessibility()) {
10142                 continue;
10143             }
10144         } else {
10145             if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
10146                 continue;
10147             }
10148         }
10149         if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10150             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10151             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10152             continue;
10153         }
10154         sceneSessionList.push_back(sceneSession);
10155     }
10156 }
10157 
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)10158 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
10159     std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
10160 {
10161     for (const auto& sceneSession : sceneSessionList) {
10162         if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
10163             TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
10164         }
10165     }
10166 }
10167 
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)10168 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
10169 {
10170     std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
10171         return a->GetZOrder() > b->GetZOrder();
10172     });
10173     std::vector<sptr<SceneSession>> result;
10174     std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
10175     for (const auto& sceneSession : sceneSessionList) {
10176         if (sceneSession == nullptr) {
10177             TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
10178             continue;
10179         }
10180         auto sessionProperty = sceneSession->GetSessionProperty();
10181         if (sessionProperty == nullptr) {
10182             TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
10183             continue;
10184         }
10185         std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
10186         auto displayId = sessionProperty->GetDisplayId();
10187         if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
10188             unaccountedSpace = unaccountedSpaceMap[displayId];
10189         } else {
10190             unaccountedSpace = GetDisplayRegion(displayId);
10191             if (unaccountedSpace == nullptr) {
10192                 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
10193                 continue;
10194             }
10195             unaccountedSpaceMap[displayId] = unaccountedSpace;
10196         }
10197         WSRect wsRect = sceneSession->GetSessionRect();
10198         SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
10199                               .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
10200         SkRegion windowRegion(windowBounds);
10201         if (unaccountedSpace->quickReject(windowRegion)) {
10202             TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10203                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10204             continue;
10205         }
10206         if (!unaccountedSpace->intersects(windowRegion)) {
10207             TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10208                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10209             continue;
10210         }
10211         result.push_back(sceneSession);
10212         unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
10213         if (unaccountedSpace->isEmpty()) {
10214             break;
10215         }
10216     }
10217     sceneSessionList = result;
10218 }
10219 
NotifyAllAccessibilityInfo()10220 void SceneSessionManager::NotifyAllAccessibilityInfo()
10221 {
10222     if (isUserBackground_) {
10223         TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
10224         return;
10225     }
10226     std::vector<sptr<SceneSession>> sceneSessionList;
10227     GetAllSceneSessionForAccessibility(sceneSessionList);
10228     FilterSceneSessionCovered(sceneSessionList);
10229 
10230     std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
10231     FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
10232 
10233     for (const auto& item : accessibilityInfo) {
10234         TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, \
10235             bundle=%{public}s, bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
10236             item->wid_, item->innerWid_, item->bundleName_.c_str(),
10237             item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
10238         for (const auto& rect : item->touchHotAreas_) {
10239             TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d," \
10240             "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
10241         }
10242     }
10243 
10244     SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
10245         WindowUpdateType::WINDOW_UPDATE_ALL);
10246 }
10247 
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)10248 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
10249     const sptr<WindowSessionProperty>& property)
10250 {
10251     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
10252     if (property == nullptr) {
10253         return windowStatus;
10254     }
10255     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
10256         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
10257         if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
10258             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
10259         }
10260     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
10261         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
10262     } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
10263         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10264     } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
10265         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
10266     }
10267     return windowStatus;
10268 }
10269 
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)10270 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
10271 {
10272     if (!SessionPermission::IsStartedByInputMethod()) {
10273         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10274         return WMError::WM_ERROR_INVALID_PERMISSION;
10275     }
10276     auto scnSession = GetSceneSession(persistentId);
10277     if (scnSession == nullptr) {
10278         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10279         return WMError::WM_ERROR_NULLPTR;
10280     }
10281 
10282     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10283         persistentId, scnSession->GetWindowType());
10284 
10285     auto sessionProperty = scnSession->GetSessionProperty();
10286     if (sessionProperty == nullptr) {
10287         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10288         return WMError::WM_ERROR_INVALID_WINDOW;
10289     }
10290     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10291     auto callingSession = GetSceneSession(callingWindowId);
10292     if (callingSession == nullptr) {
10293         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10294         callingSession = GetSceneSession(focusedSessionId_);
10295         if (callingSession == nullptr) {
10296             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10297             return WMError::WM_ERROR_INVALID_WINDOW;
10298         }
10299     }
10300     if (callingSession->IsSystemSession()) {
10301         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10302     } else {
10303         windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
10304             callingSession->GetSessionProperty());
10305     }
10306     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
10307         persistentId, windowStatus);
10308     return WMError::WM_OK;
10309 }
10310 
GetCallingWindowRect(int32_t persistentId,Rect & rect)10311 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
10312 {
10313     if (!SessionPermission::IsStartedByInputMethod()) {
10314         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10315         return WMError::WM_ERROR_INVALID_PERMISSION;
10316     }
10317     auto scnSession = GetSceneSession(persistentId);
10318     if (scnSession == nullptr) {
10319         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10320         return WMError::WM_ERROR_NULLPTR;
10321     }
10322     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10323         persistentId, scnSession->GetWindowType());
10324     auto sessionProperty = scnSession->GetSessionProperty();
10325     if (sessionProperty == nullptr) {
10326         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10327         return WMError::WM_ERROR_INVALID_WINDOW;
10328     }
10329     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10330     auto callingSession = GetSceneSession(callingWindowId);
10331     if (callingSession == nullptr) {
10332         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10333         callingSession = GetSceneSession(focusedSessionId_);
10334         if (callingSession == nullptr) {
10335             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10336             return WMError::WM_ERROR_INVALID_WINDOW;
10337         }
10338     }
10339     WSRect sessionRect = callingSession->GetSessionRect();
10340     rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
10341     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
10342         "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10343     return WMError::WM_OK;
10344 }
10345 
GetWindowModeType(WindowModeType & windowModeType)10346 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
10347 {
10348     if (!SessionPermission::IsSACalling()) {
10349         WLOGFE("GetWindowModeType permission denied!");
10350         return WMError::WM_ERROR_INVALID_PERMISSION;
10351     }
10352     windowModeType = CheckWindowModeType();
10353     return WMError::WM_OK;
10354 }
10355 
GetWindowStyleType(WindowStyleType & windowStyleType)10356 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
10357 {
10358     if (!SessionPermission::IsSACalling()) {
10359         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10360         return WMError::WM_ERROR_INVALID_PERMISSION;
10361     }
10362     auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
10363     if (isPC) {
10364         windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
10365         return WMError::WM_OK;
10366     }
10367     windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
10368         WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
10369     return WMError::WM_OK;
10370 }
10371 
CheckSceneZOrder()10372 void SceneSessionManager::CheckSceneZOrder()
10373 {
10374     auto task = [this]() {
10375         AnomalyDetection::SceneZOrderCheckProcess();
10376     };
10377     taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
10378 }
10379 
NotifyEnterRecentTask(bool enterRecent)10380 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
10381 {
10382     TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
10383     enterRecent_.store(enterRecent);
10384     SetSystemAnimatedScenes(enterRecent ?
10385         SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
10386     auto task = [this] {
10387         for (auto persistentId : gestureBackEnableWindowIdSet_) {
10388             auto sceneSession = GetSceneSession(persistentId);
10389             if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
10390                 continue;
10391             }
10392             UpdateGestureBackEnabled(persistentId);
10393         }
10394     };
10395     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
10396     return WSError::WS_OK;
10397 }
10398 
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)10399 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
10400 {
10401     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
10402         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
10403         return WMError::WM_ERROR_INVALID_PERMISSION;
10404     }
10405 
10406     if (!topNInfo.empty() || (topNum <= 0)) {
10407         return WMError::WM_ERROR_INVALID_PARAM;
10408     }
10409 
10410     TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
10411     auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
10412         if (session == nullptr) {
10413             return false;
10414         }
10415 
10416         if (topNum == 0) {
10417             return true;
10418         }
10419 
10420         if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
10421             TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
10422             return false;
10423         }
10424 
10425         MainWindowInfo info;
10426         info.pid_ = session->GetCallingPid();
10427         info.bundleName_ = session->GetSessionInfo().bundleName_;
10428         topNInfo.push_back(info);
10429         topNum--;
10430         TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
10431             topNum, info.pid_, info.bundleName_.c_str());
10432         return false;
10433     };
10434     TraverseSessionTree(func, true);
10435 
10436     return WMError::WM_OK;
10437 }
10438 
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const10439 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
10440 {
10441     if (!infos.empty()) {
10442         TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
10443         return WMError::WM_ERROR_INVALID_PARAM;
10444     }
10445     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10446         TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
10447         return WMError::WM_ERROR_INVALID_PERMISSION;
10448     }
10449     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10450     for (const auto& iter : sceneSessionMap_) {
10451         auto& session = iter.second;
10452         if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
10453             continue;
10454         }
10455         MainWindowInfo info;
10456         auto abilityInfo = session->GetSessionInfo().abilityInfo;
10457         info.pid_ = session->GetCallingPid();
10458         info.bundleName_ = session->GetSessionInfo().bundleName_;
10459         info.persistentId_ = session->GetPersistentId();
10460         if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
10461             TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
10462             info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
10463             infos.push_back(info);
10464         } else if (abilityInfo != nullptr) {
10465             info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
10466             infos.push_back(info);
10467             TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
10468                 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
10469                 info.bundleName_.c_str(), info.bundleType_);
10470         }
10471     }
10472     return WMError::WM_OK;
10473 }
10474 
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)10475 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
10476     std::vector<int32_t>& clearFailedIds)
10477 {
10478     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10479         TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
10480         return WMError::WM_ERROR_INVALID_PERMISSION;
10481     }
10482     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10483         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10484         return WMError::WM_ERROR_INVALID_PERMISSION;
10485     }
10486     clearFailedIds.clear();
10487     for (const auto persistentId : persistentIds) {
10488         auto sceneSession = GetSceneSession(persistentId);
10489         if (sceneSession == nullptr) {
10490             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
10491             clearFailedIds.push_back(persistentId);
10492             continue;
10493         }
10494         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10495             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10496             clearFailedIds.push_back(persistentId);
10497             continue;
10498         }
10499         sceneSession->Clear();
10500         TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
10501     }
10502     return WMError::WM_OK;
10503 }
10504 
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)10505 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
10506     bool enable)
10507 {
10508     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
10509         width, height, density, enable);
10510 
10511     DMHookInfo dmHookInfo;
10512     dmHookInfo.width_ = width;
10513     dmHookInfo.height_ = height;
10514     dmHookInfo.density_ = density;
10515     dmHookInfo.rotation_ = 0;
10516     dmHookInfo.enableHookRotation_ = false;
10517     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10518     return WMError::WM_OK;
10519 }
10520 
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)10521 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
10522 {
10523     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
10524         "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
10525         hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
10526 
10527     DMHookInfo dmHookInfo;
10528     dmHookInfo.width_ = hookInfo.width_;
10529     dmHookInfo.height_ = hookInfo.height_;
10530     dmHookInfo.density_ = hookInfo.density_;
10531     dmHookInfo.rotation_ = hookInfo.rotation_;
10532     dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
10533     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10534     return WMError::WM_OK;
10535 }
10536 
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)10537 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
10538 {
10539     SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
10540 }
10541 
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)10542 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
10543 {
10544     ScreenFoldData screenFoldData;
10545     WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
10546     if (ret != WMError::WM_OK) {
10547         return ret;
10548     }
10549     return CheckAndReportScreenFoldStatus(screenFoldData);
10550 }
10551 
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)10552 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
10553     ScreenFoldData& screenFoldData)
10554 {
10555     if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
10556         TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
10557         return WMError::WM_DO_NOTHING;
10558     }
10559 
10560     screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
10561     screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
10562     screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
10563     screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
10564     screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
10565     if (!screenFoldData.GetTypeCThermalWithUtil()) {
10566         TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
10567         return WMError::WM_DO_NOTHING;
10568     }
10569     AppExecFwk::ElementName element = {};
10570     WSError ret = GetFocusSessionElement(element);
10571     if (ret != WSError::WS_OK) {
10572         TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
10573         return WMError::WM_DO_NOTHING;
10574     }
10575     screenFoldData.SetFocusedPkgName(element.GetURI());
10576     return WMError::WM_OK;
10577 }
10578 
CheckAndReportScreenFoldStatus(ScreenFoldData & data)10579 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
10580 {
10581     static ScreenFoldData lastScreenHalfFoldData;
10582     if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10583         lastScreenHalfFoldData = data;
10584         return WMError::WM_DO_NOTHING;
10585     }
10586     WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
10587     if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10588         if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
10589             lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
10590         } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
10591             // if stay at half-fold less than 15s, combine this change with last
10592             data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
10593             data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
10594             data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
10595         }
10596         lastScreenHalfFoldData.SetInvalid();
10597     }
10598     WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
10599     return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
10600         currentScreenFoldStatusReportRet;
10601 }
10602 
10603 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)10604 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
10605 {
10606     if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
10607         return WMError::WM_DO_NOTHING;
10608     }
10609 
10610     int32_t ret = HiSysEventWrite(
10611         OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
10612         "FOLDSCREEN_STATE_CHANGE",
10613         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
10614         "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
10615         "LASTFOLDSTATE", data.currentScreenFoldStatus_,
10616         "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
10617         "STATE", -1,
10618         "TIME", data.currentScreenFoldStatusDuration_,
10619         "ROTATION", data.screenRotation_,
10620         "PACKAGE", data.focusedPackageName_,
10621         "ANGLE", data.postureAngle_,
10622         "TYPECTHERMAL", data.typeCThermal_,
10623         "SCREENTHERMAL", -1,
10624         "SCANGLE", -1,
10625         "ISTENT", -1);
10626     if (ret != 0) {
10627         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
10628         return WMError::WM_DO_NOTHING;
10629     }
10630     return WMError::WM_OK;
10631 }
10632 
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userid)10633 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
10634 {
10635     if (currentUserId_ != static_cast<int32_t>(userid)) {
10636         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64"", currentUserId_, userid);
10637         return;
10638     }
10639     auto secSurfaceInfoMap = secExtensionData->GetSecData();
10640     auto task = [secSurfaceInfoMap]()-> WSError {
10641         SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
10642         return WSError::WS_OK;
10643     };
10644     taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
10645 }
10646 
RegisterSecSurfaceInfoListener()10647 void SceneSessionManager::RegisterSecSurfaceInfoListener()
10648 {
10649     auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
10650         this->UpdateSecSurfaceInfo(secExtensionData, userid);
10651     };
10652     TLOGI(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener");
10653     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
10654         TLOGE(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener failed");
10655     }
10656 }
10657 
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)10658 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
10659     const AppForceLandscapeConfig& config)
10660 {
10661     if (bundleName.empty()) {
10662         TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
10663         return WSError::WS_ERROR_NULLPTR;
10664     }
10665     std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10666     appForceLandscapeMap_[bundleName] = config;
10667     TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
10668         bundleName.c_str(), config.mode_, config.homePage_.c_str());
10669     return WSError::WS_OK;
10670 }
10671 
GetAppForceLandscapeConfig(const std::string & bundleName)10672 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
10673 {
10674     if (bundleName.empty()) {
10675         return {};
10676     }
10677     std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10678     if (appForceLandscapeMap_.empty() ||
10679         appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
10680         TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
10681         return {};
10682     }
10683     return appForceLandscapeMap_[bundleName];
10684 }
10685 
TerminateSessionByPersistentId(int32_t persistentId)10686 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
10687 {
10688     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
10689         TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
10690         return WMError::WM_ERROR_INVALID_PERMISSION;
10691     }
10692     if (!SessionPermission::IsSystemAppCall()) {
10693         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
10694         return WMError::WM_ERROR_NOT_SYSTEM_APP;
10695     }
10696     auto sceneSession = GetSceneSession(persistentId);
10697     if (sceneSession == nullptr) {
10698         TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
10699         return WMError::WM_ERROR_INVALID_PARAM;
10700     }
10701     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10702         TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10703         return WMError::WM_ERROR_INVALID_PARAM;
10704     }
10705     sceneSession->Clear(true);
10706     TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
10707     return WMError::WM_OK;
10708 }
10709 
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)10710 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
10711 {
10712     rootSceneProcessBackEventFunc_ = processBackEventFunc;
10713     TLOGI(WmsLogTag::WMS_EVENT, "called");
10714 }
10715 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)10716 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
10717     const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
10718 {
10719     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10720         TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
10721         return WMError::WM_ERROR_INVALID_PERMISSION;
10722     }
10723 
10724     surfaceNodeIds.clear();
10725     TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
10726     for (auto persistentId : persistentIds) {
10727         TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
10728         auto sceneSession = GetSceneSession(persistentId);
10729         if (sceneSession == nullptr) {
10730             continue;
10731         }
10732         auto callingPid = sceneSession->GetCallingPid();
10733         auto surfaceNode = sceneSession->GetSurfaceNode();
10734         if (surfaceNode != nullptr && callingPid == pid) {
10735             surfaceNodeIds.push_back(surfaceNode->GetId());
10736             auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
10737             if (leashWinSurfaceNode != nullptr) {
10738                 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
10739                 surfaceNodeIds.push_back(persistentId);
10740             }
10741         }
10742     }
10743 
10744     return WMError::WM_OK;
10745 }
10746 
ReleaseForegroundSessionScreenLock()10747 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
10748 {
10749     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10750         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
10751         return WMError::WM_ERROR_INVALID_PERMISSION;
10752     }
10753 #ifdef POWER_MANAGER_ENABLE
10754     auto task = [this] {
10755         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10756         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
10757             if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
10758                 continue;
10759             }
10760             auto res = sceneSession->keepScreenLock_->UnLock();
10761             if (res != ERR_OK) {
10762                 TLOGNE(WmsLogTag::DEFAULT,
10763                     "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
10764                     persistentId, sceneSession->GetWindowName().c_str(), res);
10765                 return WMError::WM_ERROR_INVALID_OPERATION;
10766             }
10767             TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
10768                 persistentId, sceneSession->GetWindowName().c_str());
10769         }
10770         return WMError::WM_OK;
10771     };
10772     return taskScheduler_->PostSyncTask(task, __func__);
10773 #else
10774     TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
10775     return WMError::WM_OK;
10776 #endif
10777 }
10778 
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)10779 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
10780 {
10781     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
10782     auto task = [this, func] {
10783         closeTargetFloatWindowFunc_ = func;
10784     };
10785     taskScheduler_->PostTask(task, __func__);
10786 }
10787 
CloseTargetFloatWindow(const std::string & bundleName)10788 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
10789 {
10790     if (!SessionPermission::IsSystemServiceCalling(false)) {
10791         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
10792         return WMError::WM_ERROR_INVALID_PERMISSION;
10793     }
10794     auto task = [this, bundleName] {
10795         if (closeTargetFloatWindowFunc_) {
10796             TLOGNI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
10797             closeTargetFloatWindowFunc_(bundleName);
10798         }
10799     };
10800     taskScheduler_->PostTask(task, __func__);
10801     return WMError::WM_OK;
10802 }
10803 
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)10804 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
10805 {
10806     SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
10807 }
10808 
CloseTargetPiPWindow(const std::string & bundleName)10809 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
10810 {
10811     if (!SessionPermission::IsSystemServiceCalling(false)) {
10812         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
10813         return WMError::WM_ERROR_INVALID_PERMISSION;
10814     }
10815     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10816     for (const auto& iter : sceneSessionMap_) {
10817         auto& session = iter.second;
10818         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
10819             session->GetSessionInfo().bundleName_ == bundleName) {
10820             session->NotifyCloseExistPipWindow();
10821             break;
10822         }
10823     }
10824     return WMError::WM_OK;
10825 }
10826 
GetCurrentPiPWindowInfo(std::string & bundleName)10827 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
10828 {
10829     if (!SessionPermission::IsSystemServiceCalling(false)) {
10830         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
10831         return WMError::WM_ERROR_INVALID_PERMISSION;
10832     }
10833     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10834     for (const auto& iter : sceneSessionMap_) {
10835         auto& session = iter.second;
10836         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
10837             bundleName = session->GetSessionInfo().bundleName_;
10838             return WMError::WM_OK;
10839         }
10840     }
10841     TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
10842     return WMError::WM_OK;
10843 }
10844 
UpdateDarkColorModeToRS()10845 void SceneSessionManager::UpdateDarkColorModeToRS()
10846 {
10847     std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
10848     if (appContext == nullptr) {
10849         TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
10850         return;
10851     }
10852     std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
10853     if (config == nullptr) {
10854         TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
10855         return;
10856     }
10857     std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
10858     bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
10859     bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
10860     TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d",
10861         colorMode.c_str(), ret);
10862 }
10863 
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)10864 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
10865     std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
10866 {
10867     if (!SessionPermission::IsSystemCalling()) {
10868         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
10869         return WMError::WM_ERROR_INVALID_PERMISSION;
10870     }
10871 
10872     auto task = [this, windowIds, &windowDisplayIdMap] {
10873         for (const uint64_t windowId : windowIds) {
10874             sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
10875             if (session == nullptr) {
10876                 continue;
10877             }
10878             sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
10879             if (sessionProperty == nullptr) {
10880                 continue;
10881             }
10882 			DisplayId displayId = sessionProperty->GetDisplayId();
10883             TLOGNI(WmsLogTag::DEFAULT, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
10884                 windowId, displayId);
10885             windowDisplayIdMap.insert({windowId, displayId});
10886         }
10887         return WMError::WM_OK;
10888     };
10889     return taskScheduler_->PostSyncTask(task, __func__);
10890 }
10891 
IsLastFrameLayoutFinished(bool & isLayoutFinished)10892 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
10893 {
10894     if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
10895         TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
10896         return WSError::WS_ERROR_NULLPTR;
10897     }
10898     isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
10899     return WSError::WS_OK;
10900 }
10901 } // namespace OHOS::Rosen