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 <algorithm>
19 #include <securec.h>
20 
21 #include <ability_context.h>
22 #include <ability_manager_client.h>
23 #include <bundlemgr/launcher_service.h>
24 #include <hisysevent.h>
25 #include <parameters.h>
26 #include <hitrace_meter.h>
27 #include "ffrt_inner.h"
28 #include "parameter.h"
29 #include "publish/scb_dump_subscriber.h"
30 
31 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
32 #include <display_power_mgr_client.h>
33 #endif
34 
35 #ifdef POWER_MANAGER_ENABLE
36 #include <power_mgr_client.h>
37 #endif
38 
39 #ifdef RES_SCHED_ENABLE
40 #include "res_type.h"
41 #include "res_sched_client.h"
42 #endif
43 #include "scene_system_ability_listener.h"
44 
45 #include "color_parser.h"
46 #include "common/include/session_permission.h"
47 #include "display_manager.h"
48 #include "scene_input_manager.h"
49 #include "session/host/include/main_session.h"
50 #include "session/host/include/scb_system_session.h"
51 #include "session/host/include/scene_persistent_storage.h"
52 #include "session/host/include/session_utils.h"
53 #include "session/host/include/sub_session.h"
54 #include "session_helper.h"
55 #include "window_helper.h"
56 #include "screen_session_manager_client/include/screen_session_manager_client.h"
57 #include "singleton_container.h"
58 #include "xcollie/watchdog.h"
59 #include "session_manager_agent_controller.h"
60 #include "distributed_client.h"
61 #include "softbus_bus_center.h"
62 #include "perform_reporter.h"
63 #include "dms_reporter.h"
64 #include "res_sched_client.h"
65 #include "res_type.h"
66 #include "anomaly_detection.h"
67 #include "hidump_controller.h"
68 #include "window_pid_visibility_info.h"
69 #include "session/host/include/multi_instance_manager.h"
70 
71 #ifdef MEMMGR_WINDOW_ENABLE
72 #include "mem_mgr_client.h"
73 #include "mem_mgr_window_info.h"
74 #endif
75 
76 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
77 #include "sec_comp_enhance_kit.h"
78 #endif
79 
80 #ifdef IMF_ENABLE
81 #include <input_method_controller.h>
82 #endif // IMF_ENABLE
83 
84 namespace OHOS::Rosen {
85 namespace {
86 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
87 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
88 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
89 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
90 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
91 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
92 constexpr const char* KEY_SESSION_ID = "com.ohos.param.sessionId";
93 constexpr uint32_t MAX_BRIGHTNESS = 255;
94 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
95 constexpr int32_t DEFAULT_USERID = -1;
96 constexpr int32_t SCALE_DIMENSION = 2;
97 constexpr int32_t TRANSLATE_DIMENSION = 2;
98 constexpr int32_t ROTAION_DIMENSION = 4;
99 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
100 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
101 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
102 const std::string EMPTY_DEVICE_ID = "";
103 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
104 
105 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
106 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
107 constexpr int VALUE_MAX_WIDTH = 5;
108 constexpr int MAX_RESEND_TIMES = 6;
109 constexpr int ORIEN_MAX_WIDTH = 12;
110 constexpr int OFFSET_MAX_WIDTH = 8;
111 constexpr int SCALE_MAX_WIDTH = 8;
112 constexpr int PID_MAX_WIDTH = 8;
113 constexpr int PARENT_ID_MAX_WIDTH = 6;
114 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
115 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
116 const std::string ARG_DUMP_ALL = "-a";
117 const std::string ARG_DUMP_WINDOW = "-w";
118 const std::string ARG_DUMP_SCREEN = "-s";
119 const std::string ARG_DUMP_DISPLAY = "-d";
120 const std::string ARG_DUMP_PIPLINE = "-p";
121 const std::string ARG_DUMP_SCB = "-b";
122 const std::string ARG_DUMP_DETAIL = "-c";
123 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
124 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
125 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
126 
127 constexpr int32_t FFRT_USER_INTERACTIVE_MAX_THREAD_NUM = 5;
128 
129 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
130     {"unspecified",                         OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
131     {"landscape",                           OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
132     {"portrait",                            OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
133     {"follow_recent",                       OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
134     {"landscape_inverted",                  OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
135     {"portrait_inverted",                   OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
136     {"auto_rotation",                       OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
137     {"auto_rotation_landscape",             OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
138     {"auto_rotation_portrait",              OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
139     {"auto_rotation_restricted",            OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
140     {"auto_rotation_landscape_restricted",  OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
141     {"auto_rotation_portrait_restricted",   OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
142     {"locked",                              OHOS::AppExecFwk::DisplayOrientation::LOCKED},
143     {"auto_rotation_unspecified",           OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
144     {"follow_desktop",                      OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
145 };
146 
147 const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
148 
GetCurrentTime()149 std::string GetCurrentTime()
150 {
151     struct timespec tn;
152     clock_gettime(CLOCK_REALTIME, &tn);
153     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
154         static_cast<uint64_t>(tn.tv_nsec);
155     return std::to_string(uTime);
156 }
Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)157 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
158 {
159     return a.first < b.first;
160 }
161 
GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)162 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
163 {
164     if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
165         value = (*item.intsValue_)[0];
166         return true;
167     }
168     return false;
169 }
170 
ConfigFfrtWorkerNum()171 int ConfigFfrtWorkerNum()
172 {
173     ffrt_worker_num_param qosConfig;
174     (void)memset_s(&qosConfig, sizeof(qosConfig), -1, sizeof(qosConfig));
175     qosConfig.effectLen = 1;
176     qosConfig.qosConfigArray[0].qos = ffrt_qos_user_interactive;
177     qosConfig.qosConfigArray[0].hardLimit = FFRT_USER_INTERACTIVE_MAX_THREAD_NUM;
178     return ffrt_set_qos_worker_num(&qosConfig);
179 }
180 
GetPid()181 int32_t GetPid()
182 {
183     static int32_t pid = static_cast<int32_t>(getpid());
184     return pid;
185 }
186 
187 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
188 public:
189     BundleStatusCallback() = default;
190     virtual ~BundleStatusCallback() = default;
191 
192     void OnBundleStateChanged(const uint8_t installType,
193         const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
194 
195     void OnBundleAdded(const std::string& bundleName, const int userId) override
196     {
197         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
198     }
199 
200     void OnBundleUpdated(const std::string& bundleName, const int userId) override
201     {
202         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
203     }
204 
205     void OnBundleRemoved(const std::string& bundleName, const int userId) override
206     {
207         SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
208     }
209 };
210 } // namespace
211 
CreateInstance()212 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
213 {
214     sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
215     sessionManager->Init();
216     return sessionManager;
217 }
218 
GetInstance()219 SceneSessionManager& SceneSessionManager::GetInstance()
220 {
221     static sptr<SceneSessionManager> instance = CreateInstance();
222     return *instance;
223 }
224 
SceneSessionManager()225 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
226 {
227     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
228     currentUserId_ = DEFAULT_USERID;
229     launcherService_ = sptr<AppExecFwk::LauncherService>::MakeSptr();
230     if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
231         WLOGFE("Failed to register bundle status callback.");
232     }
233 
234     collaboratorDeathRecipient_ = sptr<AgentDeathRecipient>::MakeSptr(
235         [this](const sptr<IRemoteObject>& remoteObject) { this->ClearAllCollaboratorSessions(); });
236 }
237 
~SceneSessionManager()238 SceneSessionManager::~SceneSessionManager()
239 {
240     ScbDumpSubscriber::UnSubscribe(scbDumpSubscriber_);
241 }
242 
Init()243 void SceneSessionManager::Init()
244 {
245     auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
246     bool isScbCoreEnabled = (deviceType == "phone" || deviceType == "2in1" || deviceType == "tablet" ||
247         deviceType == "wearable") && system::GetParameter("persist.window.scbcore.enable", "1") == "1";
248     Session::SetScbCoreEnabled(isScbCoreEnabled);
249 
250     constexpr uint64_t interval = 5 * 1000; // 5 second
251     if (HiviewDFX::Watchdog::GetInstance().AddThread(
252         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
253         WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
254     }
255 
256     bundleMgr_ = GetBundleManager();
257 
258     LoadWindowSceneXml();
259     LoadWindowParameter();
260     InitPrepareTerminateConfig();
261 
262     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(sptr<DisplayChangeListener>::MakeSptr());
263 
264     // create handler for inner command at server
265     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
266     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
267     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
268     if (ret != 0) {
269         WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
270     }
271     taskScheduler_->SetExportHandler(eventHandler_);
272 
273     ret = ConfigFfrtWorkerNum();
274     TLOGI(WmsLogTag::WMS_MAIN, "FFRT user interactive qos max thread number: %{public}d, retcode: %{public}d",
275         FFRT_USER_INTERACTIVE_MAX_THREAD_NUM, ret);
276 
277     listenerController_ = std::make_shared<SessionListenerController>();
278 
279     scbSessionHandler_ = sptr<ScbSessionHandler>::MakeSptr();
280     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
281     StartWindowInfoReportLoop();
282     WLOGI("SSM init success.");
283 
284     RegisterAppListener();
285     openDebugTrace_ = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
286     isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1")  == "1";
287     SceneInputManager::GetInstance().Init();
288 
289     // MMI window state error check
290     int32_t retCode = MMI::InputManager::GetInstance()->
291         RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
292         this->NotifyWindowStateErrorFromMMI(pid, persistentId);
293     });
294     TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
295 
296     scbDumpSubscriber_ = ScbDumpSubscriber::Subscribe();
297     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
298         MultiInstanceManager::GetInstance().Init(bundleMgr_, taskScheduler_);
299         MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
300     }
301 }
302 
InitScheduleUtils()303 void SceneSessionManager::InitScheduleUtils()
304 {
305 #ifdef RES_SCHED_ENABLE
306     SCBThreadInfo threadInfo = {
307         .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
308         .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
309     };
310     std::unordered_map<std::string, std::string> payload {
311         { "pid", threadInfo.scbPid_ },
312         { "tid", threadInfo.scbTid_ },
313         { "uid", threadInfo.scbUid_ },
314         { "bundleName", threadInfo.scbBundleName_ },
315     };
316     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
317     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
318     auto task = [threadInfo = std::move(threadInfo)]() mutable {
319         threadInfo.ssmThreadName_ = "OS_SceneSession";
320         threadInfo.ssmTid_ = std::to_string(gettid());
321         const int32_t userInteraction = 2;
322         std::unordered_map<std::string, std::string> payload{
323             { "pid", threadInfo.scbPid_ },
324             { "tid", threadInfo.ssmTid_ },
325             { "uid", threadInfo.scbUid_ },
326             { "extType", "10002" },
327             { "cgroupPrio", "1" },
328             { "isSa", "0" },
329             { "threadName", threadInfo.ssmThreadName_ }
330         };
331         uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
332         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
333         TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
334         sptr<ISystemAbilityManager> systemAbilityManager =
335             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
336         if (!systemAbilityManager) {
337             TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
338             return;
339         }
340         auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
341         int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
342         if (ret != ERR_OK) {
343             TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
344         }
345     };
346     taskScheduler_->PostAsyncTask(task, "changeQosTask");
347 #endif
348 }
349 
RegisterAppListener()350 void SceneSessionManager::RegisterAppListener()
351 {
352     appAnrListener_ = sptr<AppAnrListener>::MakeSptr();
353     auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
354     if (appMgrClient == nullptr) {
355         WLOGFE("appMgrClient is nullptr.");
356     } else {
357         auto ret = static_cast<int32_t>(appMgrClient->RegisterAppDebugListener(appAnrListener_));
358         WLOGFI("Register app debug listener, %{public}d.", ret);
359     }
360 }
361 
LoadWindowParameter()362 void SceneSessionManager::LoadWindowParameter()
363 {
364     const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "HandsetSmartWindow");
365     if (multiWindowUIType == "HandsetSmartWindow") {
366         systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW;
367     } else if (multiWindowUIType == "FreeFormMultiWindow") {
368         systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW;
369     } else if (multiWindowUIType == "TabletSmartWindow") {
370         systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW;
371     } else {
372         WLOGFE("unknown multiWindowUIType:%{public}s.", multiWindowUIType.c_str());
373     }
374     appWindowSceneConfig_.multiWindowUIType_ = multiWindowUIType;
375 }
376 
LoadWindowSceneXml()377 void SceneSessionManager::LoadWindowSceneXml()
378 {
379     if (WindowSceneConfig::LoadConfigXml()) {
380         if (WindowSceneConfig::GetConfig().IsMap()) {
381             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
382         }
383         ConfigWindowSceneXml();
384     } else {
385         WLOGFE("Load window scene xml failed");
386     }
387     ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
388         appWindowSceneConfig_.keyboardAnimationOut_);
389 }
390 
InitPrepareTerminateConfig()391 void SceneSessionManager::InitPrepareTerminateConfig()
392 {
393     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
394     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
395         PREPARE_TERMINATE_ENABLE_SIZE);
396     WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
397     if (retSysParam > 0 && !std::strcmp(value, "true")) {
398         isPrepareTerminateEnable_ = true;
399     }
400 }
401 
ConfigWindowSceneXml()402 void SceneSessionManager::ConfigWindowSceneXml()
403 {
404     const auto& config = WindowSceneConfig::GetConfig();
405     WindowSceneConfig::ConfigItem item = config["windowEffect"];
406     if (item.IsMap()) {
407         ConfigWindowEffect(item);
408     }
409     item = config["decor"];
410     if (item.IsMap()) {
411         ConfigDecor(item);
412     }
413 
414     item = config["backgroundswitch"];
415     int32_t param = -1;
416     systemConfig_.backgroundswitch = GetSingleIntItem(item, param) && param == 1;
417     WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
418     item = config["defaultWindowMode"];
419     if (GetSingleIntItem(item, param) &&
420         (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
421         param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
422         systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
423     }
424     item = config["defaultMaximizeMode"];
425     if (GetSingleIntItem(item, param) &&
426         (param == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
427          param == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
428         SceneSession::maximizeMode_ = static_cast<MaximizeMode>(param);
429     }
430     item = config["keyboardAnimation"];
431     if (item.IsMap()) {
432         ConfigKeyboardAnimation(item);
433     }
434     item = config["maxFloatingWindowSize"];
435     if (GetSingleIntItem(item, param)) {
436         systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(param);
437     }
438     item = config["windowAnimation"];
439     if (item.IsMap()) {
440         ConfigWindowAnimation(item);
441     }
442     item = config["startWindowTransitionAnimation"];
443     if (item.IsMap()) {
444         ConfigStartingWindowAnimation(item);
445     }
446     ConfigFreeMultiWindow();
447     ConfigWindowSizeLimits();
448     ConfigSnapshotScale();
449     ConfigWindowSceneXml(config);
450 }
451 
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)452 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
453 {
454     WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
455     if (item.IsMap()) {
456         ConfigSystemUIStatusBar(item);
457     }
458     item = config["backgroundScreenLock"].GetProp("enable");
459     if (item.IsBool()) {
460         appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
461     }
462     item = config["rotationMode"];
463     if (item.IsString()) {
464         appWindowSceneConfig_.rotationMode_ = item.stringValue_;
465     }
466     item = config["immersive"];
467     if (item.IsMap()) {
468         ConfigWindowImmersive(item);
469     }
470     item = config["supportTypeFloatWindow"].GetProp("enable");
471     if (item.IsBool()) {
472         systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
473     }
474 }
475 
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)476 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
477 {
478     AppWindowSceneConfig config;
479     WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
480     if (item.IsMap()) {
481         if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
482             appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
483                 config.windowImmersive_.desktopStatusBarConfig_;
484         }
485     }
486     item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
487     if (item.IsMap()) {
488         if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
489             appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
490                 config.windowImmersive_.upDownStatusBarConfig_;
491         }
492     }
493     item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
494     if (item.IsMap()) {
495         if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
496             appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
497                 config.windowImmersive_.leftRightStatusBarConfig_;
498         }
499     }
500 }
501 
ConfigStatusBar(const WindowSceneConfig::ConfigItem& config, StatusBarConfig& statusBarConfig)502 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
503     StatusBarConfig& statusBarConfig)
504 {
505     WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
506     if (item.IsBool()) {
507         statusBarConfig.showHide_ = item.boolValue_;
508     }
509     item = config["contentColor"];
510     if (item.IsString()) {
511         statusBarConfig.contentColor_ = item.stringValue_;
512     }
513     item = config["backgroundColor"];
514     if (item.IsString()) {
515         statusBarConfig.backgroundColor_ = item.stringValue_;
516     }
517     return true;
518 }
519 
ConfigFreeMultiWindow()520 void SceneSessionManager::ConfigFreeMultiWindow()
521 {
522     const auto& config = WindowSceneConfig::GetConfig();
523     WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
524     if (freeMultiWindowConfig.IsMap()) {
525         auto supportItem = freeMultiWindowConfig.GetProp("enable");
526         if (supportItem.IsBool()) {
527             systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
528         }
529         auto item = freeMultiWindowConfig["decor"];
530         if (item.IsMap()) {
531             ConfigDecor(item, false);
532         }
533         int32_t param = -1;
534         item = freeMultiWindowConfig["defaultWindowMode"];
535         if (GetSingleIntItem(item, param) &&
536             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
537             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
538             systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
539                 static_cast<WindowMode>(static_cast<uint32_t>(param));
540         }
541         item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
542         if (GetSingleIntItem(item, param) && (param > 0)) {
543             systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
544         }
545     }
546 }
547 
LoadFreeMultiWindowConfig(bool enable)548 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
549 {
550     FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
551     if (enable) {
552         systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
553         systemConfig_.decorModeSupportInfo_ = freeMultiWindowConfig.decorModeSupportInfo_;
554         systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
555     } else {
556         const auto& config = WindowSceneConfig::GetConfig();
557         auto item = config["decor"];
558         if (item.IsMap()) {
559             ConfigDecor(item, true);
560         }
561         int32_t param = -1;
562         item = config["defaultWindowMode"];
563         if (GetSingleIntItem(item, param) &&
564             (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
565             param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
566             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
567         }
568     }
569     systemConfig_.freeMultiWindowEnable_ = enable;
570     rsInterface_.SetFreeMultiWindowStatus(enable);
571 }
572 
GetSystemSessionConfig() const573 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
574 {
575     return systemConfig_;
576 }
577 
SwitchFreeMultiWindow(bool enable)578 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
579 {
580     if (!systemConfig_.freeMultiWindowSupport_) {
581         TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
582         return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
583     }
584     LoadFreeMultiWindowConfig(enable);
585     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
586     for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
587         auto sceneSession = item->second;
588         if (sceneSession == nullptr) {
589             continue;
590         }
591         auto property = sceneSession->GetSessionProperty();
592         if (property == nullptr) {
593             continue;
594         }
595         bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
596             property->GetIsUIExtFirstSubWindow();
597         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
598             sceneSession->SwitchFreeMultiWindow(enable);
599         }
600     }
601     WindowStyleType type = enable ?
602             WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
603     SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
604     return WSError::WS_OK;
605 }
606 
GetFreeMultiWindowEnableState(bool& enable)607 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
608 {
609     enable = systemConfig_.freeMultiWindowEnable_;
610     return WSError::WS_OK;
611 }
612 
SetSessionContinueState(const sptr<IRemoteObject>& token, const ContinueState& continueState)613 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject>& token,
614     const ContinueState& continueState)
615 {
616     TLOGI(WmsLogTag::DEFAULT, "Enter");
617     auto task = [this, token, continueState]() {
618         sptr <SceneSession> sceneSession = FindSessionByToken(token);
619         if (sceneSession == nullptr) {
620             TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
621             return WSError::WS_ERROR_INVALID_PARAM;
622         }
623         sceneSession->SetSessionInfoContinueState(continueState);
624         DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
625             static_cast<AAFwk::ContinueState>(continueState));
626         TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
627             sceneSession->GetPersistentId(), continueState);
628         return WSError::WS_OK;
629     };
630     return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
631 }
632 
ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)633 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
634 {
635     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
636     if (item.IsBool()) {
637         if (mainConfig) {
638             systemConfig_.isSystemDecorEnable_ = item.boolValue_;
639         } else {
640             systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
641         }
642         bool decorEnable = item.boolValue_;
643         uint32_t support = 0;
644         std::vector<std::string> supportedModes;
645         item = decorConfig["supportedMode"];
646         if (item.IsStrings()) {
647             supportedModes = *item.stringsValue_;
648         }
649         for (auto mode : supportedModes) {
650             if (mode == "fullscreen") {
651                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
652             } else if (mode == "floating") {
653                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
654             } else if (mode == "pip") {
655                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
656             } else if (mode == "split") {
657                 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
658                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
659             } else {
660                 WLOGFW("Invalid supporedMode");
661                 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
662                 break;
663             }
664         }
665         if (mainConfig && item.IsStrings()) {
666             systemConfig_.decorModeSupportInfo_ = support;
667         }
668         if (!mainConfig && item.IsStrings()) {
669             systemConfig_.freeMultiWindowConfig_.decorModeSupportInfo_ = support;
670         }
671     }
672 }
673 
AddAlphaToColor(float alpha, std::string& color)674 static void AddAlphaToColor(float alpha, std::string& color)
675 {
676     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
677         return;
678     }
679 
680     uint32_t alphaValue = 0xFF * alpha;
681     std::stringstream ss;
682     ss << std::hex << alphaValue;
683     std::string strAlpha = ss.str();
684     if (strAlpha.size() == 1) {
685         strAlpha.append(1, '0');
686     }
687 
688     color.insert(1, strAlpha);
689 }
690 
IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)691 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
692 {
693     return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
694         (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
695         AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
696 }
697 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)698 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
699 {
700     AppWindowSceneConfig config;
701     // config corner radius
702     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
703     if (item.IsMap()) {
704         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
705             appWindowSceneConfig_ = config;
706         }
707     }
708 
709     // config shadow
710     item = effectConfig["appWindows"]["shadow"]["focused"];
711     if (item.IsMap()) {
712         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
713             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
714         }
715     }
716 
717     item = effectConfig["appWindows"]["shadow"]["unfocused"];
718     if (item.IsMap()) {
719         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
720             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
721         }
722     }
723 
724     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
725     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
726 
727     WLOGFI("Config window effect successfully");
728 }
729 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)730 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
731 {
732     std::map<std::string, float> stringToCornerRadius = {
733         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
734         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
735     };
736 
737     if (item.IsString()) {
738         auto value = item.stringValue_;
739         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
740             out = stringToCornerRadius[value];
741             return true;
742         }
743     }
744     return false;
745 }
746 
SetEnableInputEvent(bool enabled)747 void SceneSessionManager::SetEnableInputEvent(bool enabled)
748 {
749     TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
750     enableInputEvent_ = enabled;
751 }
752 
IsInputEventEnabled()753 bool SceneSessionManager::IsInputEventEnabled()
754 {
755     return enableInputEvent_;
756 }
757 
ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)758 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
759 {
760     for (const auto& persistentId : alivePersistentIds_) {
761         auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
762         if (it != recoveredPersistentIds.end()) {
763             continue;
764         }
765         auto sceneSession = GetSceneSession(persistentId);
766         if (sceneSession == nullptr) {
767             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
768             continue;
769         }
770         if (sceneSession->IsRecovered()) {
771             TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
772             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
773             visibleWindowCountMap_.erase(sceneSession->GetCallingPid());
774             EraseSceneSessionAndMarkDirtyLockFree(persistentId);
775             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
776                 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
777                 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
778             }
779         }
780     }
781 }
782 
UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)783 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
784 {
785     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
786         recoveredPersistentIds.size(), currentUserId_);
787 
788     auto task = [this, recoveredPersistentIds]() {
789         ClearUnrecoveredSessions(recoveredPersistentIds);
790         std::list<AAFwk::SessionInfo> abilitySessionInfos;
791         for (const auto& persistentId : recoveredPersistentIds) {
792             if (failRecoveredPersistentIdSet_.count(persistentId)) {
793                 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
794                 continue;
795             }
796             auto sceneSession = GetSceneSession(persistentId);
797             if (sceneSession == nullptr) {
798                 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
799                 continue;
800             }
801             const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
802             if (!abilitySessionInfo) {
803                 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
804                 continue;
805             }
806             TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
807             abilitySessionInfos.emplace_back(*abilitySessionInfo);
808         }
809         std::vector<int32_t> unrecoverableSessionIds;
810         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
811             abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
812         TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
813             unrecoverableSessionIds.size());
814         for (const auto& sessionId : unrecoverableSessionIds) {
815             auto sceneSession = GetSceneSession(sessionId);
816             if (sceneSession == nullptr) {
817                 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
818                     sessionId);
819                 continue;
820             }
821             const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
822             if (!scnSessionInfo) {
823                 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
824                 continue;
825             }
826             TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
827             sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
828         }
829         RemoveFailRecoveredSession();
830     };
831     return taskScheduler_->PostAsyncTask(task, "UpdateSessionInfoBySCB");
832 }
833 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig, WindowShadowConfig& outShadow)834 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
835     WindowShadowConfig& outShadow)
836 {
837     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
838     if (item.IsString()) {
839         auto color = item.stringValue_;
840         uint32_t colorValue;
841         if (!ColorParser::Parse(color, colorValue)) {
842             return false;
843         }
844         outShadow.color_ = color;
845     }
846 
847     item = shadowConfig["offsetX"];
848     if (item.IsFloats()) {
849         auto offsetX = *item.floatsValue_;
850         if (offsetX.size() != 1) {
851             return false;
852         }
853         outShadow.offsetX_ = offsetX[0];
854     }
855 
856     item = shadowConfig["offsetY"];
857     if (item.IsFloats()) {
858         auto offsetY = *item.floatsValue_;
859         if (offsetY.size() != 1) {
860             return false;
861         }
862         outShadow.offsetY_ = offsetY[0];
863     }
864 
865     item = shadowConfig["alpha"];
866     if (item.IsFloats()) {
867         auto alpha = *item.floatsValue_;
868         if (alpha.size() != 1 ||
869             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
870             return false;
871         }
872         outShadow.alpha_ = alpha[0];
873     }
874 
875     item = shadowConfig["radius"];
876     if (item.IsFloats()) {
877         auto radius = *item.floatsValue_;
878         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
879             return false;
880         }
881         outShadow.radius_ = radius[0];
882     }
883 
884     return true;
885 }
886 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item, KeyboardSceneAnimationConfig& config)887 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
888     KeyboardSceneAnimationConfig& config)
889 {
890     if (item.IsMap() && item.mapValue_->count("curve")) {
891         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
892         config.curveType_ = curveType;
893         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
894             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
895             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
896             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
897             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
898         }
899     }
900 
901     const WindowSceneConfig::ConfigItem& duration = item["duration"];
902     if (duration.IsInts()) {
903         auto numbers = *duration.intsValue_;
904         if (numbers.size() == 1) {
905             config.duration_ = static_cast<uint32_t>(numbers[0]);
906         }
907     }
908 }
909 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)910 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
911 {
912     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
913     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
914 
915     // config system animation
916     const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
917     systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
918         {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
919         appConfigIn.duration_);
920     const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
921     systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
922         {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
923         appConfigOut.duration_);
924 }
925 
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn, KeyboardSceneAnimationConfig& animationOut)926 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
927     KeyboardSceneAnimationConfig& animationOut)
928 {
929     if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
930         TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
931             "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
932             systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
933             systemConfig_.animationOut_.duration_);
934         return;
935     }
936 
937     // default animation curve params
938     constexpr char CURVETYPE[] = "interpolatingSpring";
939     constexpr float IN_CTRLX1 = 0.0f;
940     constexpr float OUT_CTRLX1 = 4.0f;
941     constexpr float CTRLY1 = 1.0f;
942     constexpr float CTRLX2 = 342.0f;
943     constexpr float CTRLY2 = 37.0f;
944     constexpr uint32_t DURATION = 150;
945     std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
946     std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
947 
948     // update system config for client
949     systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
950     systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
951 
952     // update app config for server
953     animationIn.curveType_ = CURVETYPE;
954     animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
955     animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
956     animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
957     animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
958     animationIn.duration_ = DURATION;
959 
960     animationOut.curveType_ = CURVETYPE;
961     animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
962     animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
963     animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
964     animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
965     animationOut.duration_ = DURATION;
966     TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
967 }
968 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)969 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
970 {
971     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
972     if (item.IsMap() && item.mapValue_->count("curve")) {
973         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
974         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
975         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
976             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
977             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
978             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
979             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
980         }
981     }
982     item = windowAnimationConfig["timing"]["duration"];
983     if (item.IsInts() && item.intsValue_->size() == 1) {
984         auto duration = *item.intsValue_;
985         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
986     }
987     item = windowAnimationConfig["scale"];
988     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
989         auto scales = *item.floatsValue_;
990         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
991         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
992     }
993     item = windowAnimationConfig["rotation"];
994     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
995         auto rotations = *item.floatsValue_;
996         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
997         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
998         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
999         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1000     }
1001     item = windowAnimationConfig["translate"];
1002     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1003         auto translates = *item.floatsValue_;
1004         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1005         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1006     }
1007     item = windowAnimationConfig["opacity"];
1008     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1009         auto opacity = *item.floatsValue_;
1010         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1011     }
1012 }
1013 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)1014 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1015 {
1016     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1017     auto item = configItem.GetProp("enable");
1018     if (item.IsBool()) {
1019         config.enabled_ = item.boolValue_;
1020     }
1021     item = configItem["timing"];
1022     if (item.IsMap() && item.mapValue_->count("curve")) {
1023         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1024     }
1025     item = configItem["timing"]["duration"];
1026     if (item.IsInts() && item.intsValue_->size() == 1) {
1027         config.duration_ = (*item.intsValue_)[0];
1028     }
1029     item = configItem["opacityStart"];
1030     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1031         config.opacityStart_ = (*item.floatsValue_)[0];
1032     }
1033     item = configItem["opacityEnd"];
1034     if (item.IsFloats() && item.floatsValue_->size() == 1) {
1035         config.opacityEnd_ = (*item.floatsValue_)[0];
1036     }
1037 }
1038 
CreateCurve( const WindowSceneConfig::ConfigItem& curveConfig)1039 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1040     const WindowSceneConfig::ConfigItem& curveConfig)
1041 {
1042     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1043         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1044     static std::unordered_set<std::string> paramCurveSet = {
1045         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1046 
1047     std::string curveName = "easeOut";
1048     const auto& nameItem = curveConfig.GetProp("name");
1049     if (!nameItem.IsString()) {
1050         return {curveName, {}};
1051     }
1052 
1053     std::string name = nameItem.stringValue_;
1054     std::vector<float> curveParams;
1055 
1056     if (paramCurveSet.find(name) != paramCurveSet.end()) {
1057         curveName = name;
1058         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1059         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1060             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1061                 curveParams.begin());
1062         }
1063     } else {
1064         auto iter = curveSet.find(name);
1065         if (iter != curveSet.end()) {
1066             curveName = name;
1067         }
1068     }
1069 
1070     return {curveName, curveParams};
1071 }
1072 
ConfigWindowSizeLimits()1073 void SceneSessionManager::ConfigWindowSizeLimits()
1074 {
1075     const auto& config = WindowSceneConfig::GetConfig();
1076     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1077     if (item.IsMap()) {
1078         ConfigMainWindowSizeLimits(item);
1079     }
1080 
1081     item = config["subWindowSizeLimits"];
1082     if (item.IsMap()) {
1083         ConfigSubWindowSizeLimits(item);
1084     }
1085 }
1086 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)1087 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1088 {
1089     auto item = mainWindowSizeConifg["miniWidth"];
1090     if (item.IsInts()) {
1091         auto numbers = *item.intsValue_;
1092         if (numbers.size() == 1) {
1093             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1094         }
1095     }
1096 
1097     item = mainWindowSizeConifg["miniHeight"];
1098     if (item.IsInts()) {
1099         auto numbers = *item.intsValue_;
1100         if (numbers.size() == 1) {
1101             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1102         }
1103     }
1104 }
1105 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)1106 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1107 {
1108     auto item = subWindowSizeConifg["miniWidth"];
1109     if (item.IsInts()) {
1110         auto numbers = *item.intsValue_;
1111         if (numbers.size() == 1) {
1112             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1113         }
1114     }
1115 
1116     item = subWindowSizeConifg["miniHeight"];
1117     if (item.IsInts()) {
1118         auto numbers = *item.intsValue_;
1119         if (numbers.size() == 1) {
1120             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1121         }
1122     }
1123 }
1124 
ConfigSnapshotScale()1125 void SceneSessionManager::ConfigSnapshotScale()
1126 {
1127     const auto& config = WindowSceneConfig::GetConfig();
1128     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1129     if (item.IsFloats()) {
1130         auto snapshotScale = *item.floatsValue_;
1131         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1132             return;
1133         }
1134         snapshotScale_ = snapshotScale[0];
1135     }
1136 }
1137 
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)1138 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1139 {
1140     TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1141     WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1142     if (item.IsInts() && item.intsValue_->size() == 1) {
1143         bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1144         appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1145         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1146             appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1147     }
1148 
1149     item = statusBarConfig["immersiveStatusBarBgColor"];
1150     if (item.IsString()) {
1151         auto color = item.stringValue_;
1152         uint32_t colorValue;
1153         if (!ColorParser::Parse(color, colorValue)) {
1154             return;
1155         }
1156         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1157         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1158             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1159     }
1160 
1161     item = statusBarConfig["immersiveStatusBarContentColor"];
1162     if (item.IsString()) {
1163         auto color = item.stringValue_;
1164         uint32_t colorValue;
1165         if (!ColorParser::Parse(color, colorValue)) {
1166             return;
1167         }
1168         appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1169         TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1170             appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1171     }
1172 }
1173 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)1174 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1175 {
1176     rootSceneContextWeak_ = contextWeak;
1177 }
1178 
GetRootSceneSession()1179 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1180 {
1181     auto task = [this] {
1182         if (rootSceneSession_ != nullptr) {
1183             return rootSceneSession_;
1184         }
1185         system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1186         rootSceneSession_ = sptr<RootSceneSession>::MakeSptr();
1187         rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1188         AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1189         return rootSceneSession_;
1190     };
1191     return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1192 }
1193 
GetRootSessionAvoidSessionRect(AvoidAreaType type)1194 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1195 {
1196     sptr<RootSceneSession> rootSession = GetRootSceneSession();
1197     if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1198         return {};
1199     }
1200     DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1201     std::vector<sptr<SceneSession>> sessionVector;
1202     switch (type) {
1203         case AvoidAreaType::TYPE_SYSTEM: {
1204             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1205             break;
1206         }
1207         case AvoidAreaType::TYPE_KEYBOARD: {
1208             sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1209             break;
1210         }
1211         default: {
1212             TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1213             return {};
1214         }
1215     }
1216 
1217     for (auto& session : sessionVector) {
1218         if (!session->IsVisible()) {
1219             continue;
1220         }
1221         const WSRect rect = session->GetSessionRect();
1222         TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1223         return rect;
1224     }
1225     return {};
1226 }
1227 
GetSceneSession(int32_t persistentId)1228 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1229 {
1230     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1231     auto iter = sceneSessionMap_.find(persistentId);
1232     if (iter == sceneSessionMap_.end()) {
1233         WLOGFD("Error found scene session with id: %{public}d", persistentId);
1234         return nullptr;
1235     }
1236     return iter->second;
1237 }
1238 
GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)1239 sptr<SceneSession> SceneSessionManager::GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)
1240 {
1241     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1242     for (const auto &item : sceneSessionMap_) {
1243         auto sceneSession = item.second;
1244         if (!sceneSession) {
1245             return nullptr;
1246         }
1247         if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1248             sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1249             sceneSession->GetSessionInfo().appInstanceKey_ != info.instanceKey_ ||
1250             sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1251             continue;
1252         }
1253         const auto& sessionModuleName = sceneSession->GetSessionInfo().moduleName_;
1254         const auto& sessionAbilityName = sceneSession->GetSessionInfo().abilityName_;
1255         if (info.isAtomicService_) {
1256             if ((sessionModuleName.empty() || sessionModuleName == info.moduleName_) &&
1257                 (sessionAbilityName.empty() || sessionAbilityName == info.abilityName_)) {
1258                 return sceneSession;
1259             }
1260         } else if (sessionModuleName == info.moduleName_ && sessionAbilityName == info.abilityName_) {
1261             return sceneSession;
1262         }
1263     }
1264     return nullptr;
1265 }
1266 
GetSceneSessionByType(WindowType type)1267 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1268 {
1269     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1270     for (const auto& [_, sceneSession] : sceneSessionMap_) {
1271         if (sceneSession && sceneSession->GetWindowType() == type) {
1272             return sceneSession;
1273         }
1274     }
1275     return nullptr;
1276 }
1277 
GetSceneSessionVectorByType( WindowType type, uint64_t displayId)1278 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(
1279     WindowType type, uint64_t displayId)
1280 {
1281     if (displayId == DISPLAY_ID_INVALID) {
1282         TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1283         return {};
1284     }
1285     std::vector<sptr<SceneSession>> sceneSessionVector;
1286     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1287     for (const auto &item : sceneSessionMap_) {
1288         auto sceneSession = item.second;
1289         if (sceneSession->GetWindowType() == type &&
1290             sceneSession->GetSessionProperty() &&
1291             sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1292             sceneSessionVector.emplace_back(sceneSession);
1293         }
1294     }
1295 
1296     return sceneSessionVector;
1297 }
1298 
UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession, sptr<WindowSessionProperty> property)1299 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1300     sptr<WindowSessionProperty> property)
1301 {
1302     if (property == nullptr) {
1303         TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1304         return WSError::WS_ERROR_NULLPTR;
1305     }
1306     if (sceneSession == nullptr) {
1307         TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1308         return WSError::WS_ERROR_NULLPTR;
1309     }
1310     auto parentPersistentId = property->GetParentPersistentId();
1311     sceneSession->SetParentPersistentId(parentPersistentId);
1312     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1313         auto parentSession = GetSceneSession(parentPersistentId);
1314         if (parentSession == nullptr) {
1315             TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1316             return WSError::WS_ERROR_NULLPTR;
1317         }
1318         parentSession->BindDialogSessionTarget(sceneSession);
1319         parentSession->BindDialogToParentSession(sceneSession);
1320         sceneSession->SetParentSession(parentSession);
1321         TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1322             sceneSession->GetPersistentId(), parentPersistentId);
1323     }
1324     return WSError::WS_OK;
1325 }
1326 
CreateSpecificSessionCallback()1327 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1328 {
1329     sptr<SceneSession::SpecificSessionCallback> specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1330     specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1331         return this->RequestSceneSession(sessionInfo, property);
1332     };
1333     specificCb->onDestroy_ = [this](const int32_t persistentId) {
1334         return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1335     };
1336     specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1337         this->ClearDisplayStatusBarTemporarilyFlags();
1338     };
1339     specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1340         this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1341     };
1342     specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type, uint64_t displayId) {
1343         return this->GetSceneSessionVectorByType(type, displayId);
1344     };
1345     specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1346         this->UpdateAvoidArea(persistentId);
1347     };
1348     specificCb->onUpdateAvoidAreaByType_ = [this](int32_t persistentId, AvoidAreaType type) {
1349         this->UpdateAvoidAreaByType(persistentId, type);
1350     };
1351     specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1352         this->UpdateOccupiedAreaIfNeed(persistentId);
1353     };
1354     specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1355         this->NotifyWindowInfoChange(persistentId, type);
1356     };
1357     specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1358         this->NotifyMMIWindowPidChange(windowId, startMoving);
1359     };
1360     specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1361         this->NotifySessionTouchOutside(persistentId);
1362     };
1363     specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1364         return this->GetAINavigationBarArea(displayId);
1365     };
1366     specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1367         this->OnOutsideDownEvent(x, y);
1368     };
1369     specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1370         return this->HandleSecureSessionShouldHide(sceneSession);
1371     };
1372     specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1373         this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1374     };
1375     specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1376         this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1377     };
1378     specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1379         this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1380     };
1381     specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1382         this->UpdateGestureBackEnabled(persistentId);
1383     };
1384     return specificCb;
1385 }
1386 
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)1387 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1388 {
1389     TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1390     auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1391     if (isSkip) {
1392         if (it == skipSurfaceNodeIds_.end()) {
1393             skipSurfaceNodeIds_.push_back(surfaceNodeId);
1394         } else {
1395             return;
1396         }
1397     } else {
1398         if (it != skipSurfaceNodeIds_.end()) {
1399             skipSurfaceNodeIds_.erase(it);
1400         } else {
1401             return;
1402         }
1403     }
1404     rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1405 }
1406 
CreateKeyboardSessionCallback()1407 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1408 {
1409     sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1410         sptr<KeyboardSession::KeyboardSessionCallback>::MakeSptr();
1411     keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1412         return this->GetSceneSession(persistentId);
1413     };
1414     keyboardCb->onGetFocusedSessionId_ = [this] {
1415         return this->GetFocusedSessionId();
1416     };
1417     keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1418     return keyboardCb;
1419 }
1420 
CheckWindowId(int32_t windowId, int32_t& pid)1421 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1422 {
1423     if (!SessionPermission::IsSystemCalling()) {
1424         TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1425         return WMError::WM_ERROR_NOT_SYSTEM_APP;
1426     }
1427 
1428     auto task = [this, windowId, &pid]() -> WMError {
1429         pid = INVALID_PID;
1430         auto sceneSession = GetSceneSession(windowId);
1431         if (sceneSession == nullptr) {
1432             WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1433             return WMError::WM_ERROR_INVALID_WINDOW;
1434         }
1435         pid = sceneSession->GetCallingPid();
1436         WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1437         return WMError::WM_OK;
1438     };
1439     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1440 }
1441 
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1442 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1443 {
1444     if (!isKeyboardPanelEnabled_) {
1445         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1446         return;
1447     }
1448     if (keyboardSession == nullptr) {
1449         TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1450         return;
1451     }
1452     auto sessionProperty = keyboardSession->GetSessionProperty();
1453     if (sessionProperty == nullptr) {
1454         TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1455         return;
1456     }
1457     DisplayId displayId = sessionProperty->GetDisplayId();
1458     const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1459     sptr<SceneSession> panelSession;
1460     if (panelVec.size() > 1) {
1461         TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1462         return;
1463     } else if (panelVec.size() == 1) {
1464         panelSession = panelVec.front();
1465         TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1466     } else {
1467         SessionInfo panelInfo = {
1468             .bundleName_ = "SCBKeyboardPanel",
1469             .moduleName_ = "SCBKeyboardPanel",
1470             .abilityName_ = "SCBKeyboardPanel",
1471             .isSystem_ = true,
1472             .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1473             .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1474             .screenId_ = static_cast<uint64_t>(displayId),
1475             .isRotable_ = true,
1476         };
1477         if (systemConfig_.IsPcWindow()) {
1478             panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1479             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1480         } else {
1481             TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1482         }
1483         panelSession = RequestSceneSession(panelInfo, nullptr);
1484         if (panelSession == nullptr) {
1485             TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1486             return;
1487         }
1488     }
1489     keyboardSession->BindKeyboardPanelSession(panelSession);
1490     panelSession->BindKeyboardSession(keyboardSession);
1491     TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1492         panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1493 }
1494 
CreateSceneSession(const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property)1495 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1496     sptr<WindowSessionProperty> property)
1497 {
1498     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1499     sptr<SceneSession> sceneSession = nullptr;
1500     if (sessionInfo.isSystem_) {
1501         sceneSession = new SCBSystemSession(sessionInfo, specificCb);
1502         WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1503     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1504         sceneSession = new MainSession(sessionInfo, specificCb);
1505         TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1506     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1507         sceneSession = new SubSession(sessionInfo, specificCb);
1508         TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1509     } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1510         sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1511         sceneSession = new KeyboardSession(sessionInfo, specificCb, keyboardCb);
1512         CreateKeyboardPanelSession(sceneSession);
1513         TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1514     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1515         sceneSession = new SystemSession(sessionInfo, specificCb);
1516         TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1517     } else {
1518         TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1519     }
1520     if (sceneSession != nullptr) {
1521         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1522         sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1523         sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1524             return this->GetAppForceLandscapeConfig(bundleName);
1525         });
1526         sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1527             this->UpdatePrivateStateAndNotify(persistentId);
1528         });
1529         sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1530             this->NotifyVisibleChange(persistentId);
1531         });
1532         if (sceneSession->moveDragController_) {
1533             sceneSession->moveDragController_->SetIsPcWindow(systemConfig_.IsPcWindow());
1534         }
1535     }
1536     return sceneSession;
1537 }
1538 
RequestSceneSession(const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property)1539 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1540     sptr<WindowSessionProperty> property)
1541 {
1542     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1543         auto session = GetSceneSession(sessionInfo.persistentId_);
1544         if (session != nullptr) {
1545             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1546             TLOGD(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1547             return session;
1548         }
1549         if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1550             TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1551                 "abilityName: %{public}s, appIndex: %{public}d",
1552                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1553                 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1554             SessionIdentityInfo identityInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_,
1555                 sessionInfo.abilityName_, sessionInfo.appIndex_, sessionInfo.appInstanceKey_,
1556                 sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1557             auto sceneSession = GetSceneSessionByIdentityInfo(identityInfo);
1558             bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1559                 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1560             if (isSingleStart) {
1561                 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1562                 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1563                     sessionInfo.persistentId_);
1564                 return sceneSession;
1565             }
1566         }
1567     }
1568 
1569     const char* const where = __func__;
1570     auto task = [this, sessionInfo, property, where] {
1571         TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession, appName: [%{public}s %{public}s %{public}s]"
1572             "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1573             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1574             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1575             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1576         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1577         if (sceneSession == nullptr) {
1578             TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1579             return sceneSession;
1580         }
1581         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
1582             WindowHelper::IsMainWindow(sceneSession->GetWindowType()) &&
1583             MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
1584             MultiInstanceManager::GetInstance().FillInstanceKeyIfNeed(sceneSession);
1585         }
1586         InitSceneSession(sceneSession, sessionInfo, property);
1587         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1588             TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1589                 where, sceneSession->GetSessionInfo().ancoSceneState);
1590             bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1591             const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1592             if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1593                 TLOGNI(WmsLogTag::WMS_LIFE,
1594                     "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1595                     where, reusedSceneSession->GetPersistentId(),
1596                     reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1597                 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1598                 return reusedSceneSession;
1599             }
1600             if (isPreHandleSuccess) {
1601                 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1602                 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1603             }
1604         }
1605         {
1606             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1607             sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1608             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
1609                 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
1610                 MultiInstanceManager::GetInstance().IncreaseInstanceKeyRefCount(sceneSession);
1611             }
1612         }
1613         PerformRegisterInRequestSceneSession(sceneSession);
1614         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1615         TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession id: %{public}d, type: %{public}d",
1616             sceneSession->GetPersistentId(), sceneSession->GetWindowType());
1617         return sceneSession;
1618     };
1619     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1620 }
1621 
InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo, const sptr<WindowSessionProperty>& property)1622 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1623     const sptr<WindowSessionProperty>& property)
1624 {
1625     auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1626     DisplayId curDisplayId = DISPLAY_ID_INVALID;
1627     if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1628         curDisplayId = sessionInfo.screenId_;
1629     } else if (callerSession) {
1630         auto callerSessionProperty = callerSession->GetSessionProperty();
1631         if (callerSessionProperty) {
1632             curDisplayId = callerSessionProperty->GetDisplayId();
1633         }
1634     }
1635     auto sessionProperty = sceneSession->GetSessionProperty();
1636     if (sessionProperty) {
1637         sessionProperty->SetDisplayId(curDisplayId);
1638         sceneSession->SetScreenId(curDisplayId);
1639         TLOGD(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
1640             curDisplayId);
1641     }
1642     sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
1643     sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
1644     if (sessionInfo.isSystem_) {
1645         sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1646         sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1647         auto rootContext = rootSceneContextWeak_.lock();
1648         sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1649     } else {
1650         TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
1651             "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
1652             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1653             sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1654     }
1655     RegisterSessionExceptionFunc(sceneSession);
1656     RegisterVisibilityChangedDetectFunc(sceneSession);
1657     // Skip FillSessionInfo when atomicService free-install start.
1658     if (!IsAtomicServiceFreeInstall(sessionInfo)) {
1659         FillSessionInfo(sceneSession);
1660     }
1661     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
1662     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1663         WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
1664     }
1665     if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
1666         sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
1667     }
1668     sceneSession->SetSystemConfig(systemConfig_);
1669     sceneSession->SetSnapshotScale(snapshotScale_);
1670     UpdateParentSessionForDialog(sceneSession, property);
1671 }
1672 
NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)1673 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1674 {
1675     auto task = [abilityName = sessionInfo.abilityName_,
1676         bundleName = sessionInfo.bundleName_, toScreenId = sessionInfo.screenId_, action, fromScreenId] {
1677         sptr<DisplayChangeInfo> info = sptr<DisplayChangeInfo>::MakeSptr();
1678         info->action_ = action;
1679         info->abilityName_ = std::move(abilityName);
1680         info->bundleName_ = std::move(bundleName);
1681         info->toScreenId_ = toScreenId;
1682         info->fromScreenId_ = fromScreenId;
1683         ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1684         TLOGNI(WmsLogTag::DMS, "Notify ability %{public}s bundle %{public}s update toScreen id: %{public}" PRIu64 ".",
1685             info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1686     };
1687     taskScheduler_->PostAsyncTask(task, __func__);
1688 }
1689 
PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)1690 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1691 {
1692     RegisterSessionSnapshotFunc(sceneSession);
1693     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1694     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1695     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1696     RegisterGetStateFromManagerFunc(sceneSession);
1697     RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
1698     RegisterAcquireRotateAnimationConfigFunc(sceneSession);
1699 }
1700 
UpdateSceneSessionWant(const SessionInfo& sessionInfo)1701 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1702 {
1703     if (sessionInfo.persistentId_ != 0) {
1704         auto session = GetSceneSession(sessionInfo.persistentId_);
1705         if (session != nullptr && sessionInfo.want != nullptr) {
1706             TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
1707             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1708                 session->SetSessionInfoWant(sessionInfo.want);
1709                 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
1710             } else {
1711                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1712             }
1713         } else {
1714             TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
1715                 session == nullptr, sessionInfo.persistentId_);
1716         }
1717     } else {
1718         TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
1719     }
1720 }
1721 
UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)1722 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
1723 {
1724     if (session != nullptr) {
1725         if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1726             FillSessionInfo(session);
1727             if (CheckCollaboratorType(session->GetCollaboratorType())) {
1728                 PreHandleCollaborator(session, persistentId);
1729             }
1730         }
1731     }
1732 }
1733 
SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)1734 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
1735 {
1736     sptr<AAFwk::SessionInfo> abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
1737     auto sessionInfo = scnSession->GetSessionInfo();
1738     sptr<ISession> iSession(scnSession);
1739     abilitySessionInfo->sessionToken = iSession->AsObject();
1740     abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
1741         std::chrono::system_clock::now()).time_since_epoch().count());
1742     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
1743     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
1744         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
1745     abilitySessionInfo->persistentId = scnSession->GetPersistentId();
1746     abilitySessionInfo->requestCode = sessionInfo.requestCode;
1747     abilitySessionInfo->resultCode = sessionInfo.resultCode;
1748     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
1749     abilitySessionInfo->startSetting = sessionInfo.startSetting;
1750     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
1751     abilitySessionInfo->userId = currentUserId_;
1752     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
1753     abilitySessionInfo->processOptions = sessionInfo.processOptions;
1754     if (sessionInfo.want != nullptr) {
1755         abilitySessionInfo->want = *sessionInfo.want;
1756     } else {
1757         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
1758             sessionInfo.moduleName_);
1759     }
1760     int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
1761     bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
1762     if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
1763         TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
1764             appIndex, sessionInfo.appIndex_);
1765     }
1766     if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
1767         TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
1768         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
1769     }
1770     auto sessionProperty = scnSession->GetSessionProperty();
1771     if (sessionProperty) {
1772         abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
1773             static_cast<int>(sessionProperty->GetDisplayId()));
1774     }
1775     abilitySessionInfo->instanceKey = sessionInfo.appInstanceKey_;
1776     return abilitySessionInfo;
1777 }
1778 
PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)1779 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
1780 {
1781     auto task = [this, persistentId, &isPrepareTerminate]() {
1782         if (!isPrepareTerminateEnable_) { // not support prepareTerminate
1783             isPrepareTerminate = false;
1784             WLOGE("not support prepareTerminate, Id:%{public}d", persistentId);
1785             return WSError::WS_OK;
1786         }
1787         auto scnSession = GetSceneSession(persistentId);
1788         if (scnSession == nullptr) {
1789             WLOGFE("PrepareTerminate scnSession is null, Id:%{public}d", persistentId);
1790             isPrepareTerminate = false;
1791             return WSError::WS_ERROR_NULLPTR;
1792         }
1793         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1794         if (scnSessionInfo == nullptr) {
1795             WLOGFE("PrepareTerminate scnSessionInfo is null, Id:%{public}d", persistentId);
1796             isPrepareTerminate = false;
1797             return WSError::WS_ERROR_NULLPTR;
1798         }
1799         auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
1800             PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
1801         TLOGI(WmsLogTag::WMS_MAIN, "PrepareTerminateAbilityBySCB Id:%{public}d isPrepareTerminate:%{public}d "
1802             "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
1803         return WSError::WS_OK;
1804     };
1805     taskScheduler_->PostSyncTask(task, "PrepareTerminate:PID:" + std::to_string(persistentId));
1806     return WSError::WS_OK;
1807 }
1808 
RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)1809 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
1810 {
1811     wptr<SceneSession> weakSceneSession(sceneSession);
1812     auto task = [this, weakSceneSession, isNewActive]() {
1813         sptr<SceneSession> scnSession = weakSceneSession.promote();
1814         if (scnSession == nullptr) {
1815             TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
1816             return WSError::WS_ERROR_NULLPTR;
1817         }
1818         auto persistentId = scnSession->GetPersistentId();
1819         if (!Session::IsScbCoreEnabled()) {
1820             scnSession->SetForegroundInteractiveStatus(true);
1821         }
1822         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
1823         TLOGI(WmsLogTag::WMS_MAIN, "Request active id:%{public}d system:%{public}u isNewActive:%{public}d",
1824             persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_), isNewActive);
1825         if (!GetSceneSession(persistentId)) {
1826             TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
1827             return WSError::WS_ERROR_INVALID_SESSION;
1828         }
1829         auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
1830         if (ret == WSError::WS_OK) {
1831             scnSession->SetExitSplitOnBackground(false);
1832         }
1833         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
1834         abilityInfoMap_.clear(); // clear cache after terminate
1835         return ret;
1836     };
1837     std::string taskName = "RequestSceneSessionActivation:PID:" +
1838         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
1839     taskScheduler_->PostAsyncTask(task, taskName);
1840     return WSError::WS_OK;
1841 }
1842 
IsKeyboardForeground()1843 bool SceneSessionManager::IsKeyboardForeground()
1844 {
1845     bool isKeyboardForeground = false;
1846     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1847     for (const auto &item : sceneSessionMap_) {
1848         auto sceneSession = item.second;
1849         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1850             isKeyboardForeground = sceneSession->IsSessionForeground();
1851             break;
1852         }
1853     }
1854 
1855     return isKeyboardForeground;
1856 }
1857 
RequestInputMethodCloseKeyboard(const int32_t persistentId)1858 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
1859 {
1860     auto sceneSession = GetSceneSession(persistentId);
1861     if (sceneSession == nullptr) {
1862         TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
1863         return;
1864     }
1865     // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
1866     if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
1867         !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
1868         TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
1869             persistentId, sceneSession->GetSessionState());
1870         sceneSession->RequestHideKeyboard(true);
1871     }
1872 }
1873 
StartUIAbilityBySCB(sptr<SceneSession>& scnSession)1874 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
1875 {
1876     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1877     if (abilitySessionInfo == nullptr) {
1878         return ERR_NULL_OBJECT;
1879     }
1880     return StartUIAbilityBySCB(abilitySessionInfo);
1881 }
1882 
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)1883 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
1884 {
1885     bool isColdStart = false;
1886     return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
1887 }
1888 
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)1889 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
1890 {
1891     auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1892     if (abilitySessionInfo == nullptr) {
1893         return ERR_NULL_OBJECT;
1894     }
1895     return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
1896 }
1897 
RequestSceneSessionActivationInner( sptr<SceneSession>& scnSession, bool isNewActive)1898 WSError SceneSessionManager::RequestSceneSessionActivationInner(
1899     sptr<SceneSession>& scnSession, bool isNewActive)
1900 {
1901     auto persistentId = scnSession->GetPersistentId();
1902     RequestInputMethodCloseKeyboard(persistentId);
1903     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1904         scnSession->SetIsStarting(true);
1905     }
1906     if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
1907         if (Session::IsScbCoreEnabled()) {
1908             if (scnSession->IsVisibleForeground()) {
1909                 RequestSessionFocusImmediately(persistentId);
1910             } else {
1911                 PostProcessFocusState state = { true, true, true, FocusChangeReason::SCB_START_APP };
1912                 scnSession->SetPostProcessFocusState(state);
1913             }
1914         } else {
1915             RequestSessionFocusImmediately(persistentId);
1916         }
1917     }
1918     if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1919         FillSessionInfo(scnSession);
1920         if (!PreHandleCollaborator(scnSession, persistentId)) {
1921             TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
1922                 persistentId, scnSession->GetSessionInfo().ancoSceneState);
1923             scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
1924             return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
1925         }
1926     }
1927     auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1928     if (!scnSessionInfo) {
1929         TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
1930         return WSError::WS_ERROR_NULLPTR;
1931     }
1932     scnSession->NotifyActivation();
1933     scnSessionInfo->isNewWant = isNewActive;
1934     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1935         scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
1936         scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
1937     }
1938     TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
1939         "module: %{public}s, uri: %{public}s, appIndex: %{public}d.", persistentId,
1940         scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
1941         scnSessionInfo->want.GetElement().GetBundleName().c_str(),
1942         scnSessionInfo->want.GetElement().GetModuleName().c_str(),
1943         scnSessionInfo->want.GetElement().GetURI().c_str(),
1944         scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0));
1945     int32_t errCode = ERR_OK;
1946     bool isColdStart = false;
1947     bool isAppSupportPhoneInPc = false;
1948     auto sessionProperty = scnSession->GetSessionProperty();
1949     if (sessionProperty != nullptr) {
1950         isAppSupportPhoneInPc = sessionProperty->GetIsAppSupportPhoneInPc();
1951     }
1952     if (systemConfig_.backgroundswitch == false || isAppSupportPhoneInPc) {
1953         TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
1954             static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1955         errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1956     } else {
1957         TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
1958             isNewActive, scnSession->GetSessionState());
1959         if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
1960             scnSession->GetSessionState() == SessionState::STATE_END) {
1961             TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
1962                 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1963             errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1964         } else {
1965             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
1966             scnSession->NotifySessionForeground(1, true);
1967         }
1968     }
1969     auto sessionInfo = scnSession->GetSessionInfo();
1970     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1971         WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
1972     }
1973     NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
1974 
1975     if (errCode != ERR_OK) {
1976         TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
1977         scnSession->NotifySessionExceptionInner(scnSessionInfo, true);
1978         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
1979             startUIAbilityErrorFunc_(
1980                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
1981         }
1982     }
1983     if (isColdStart) {
1984         TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
1985             scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
1986         scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
1987         scnSession->ResetSessionConnectState();
1988         scnSession->ResetIsActive();
1989     }
1990     return WSError::WS_OK;
1991 }
1992 
NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession, sptr<AAFwk::SessionInfo>& scnSessionInfo)1993 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
1994     sptr<AAFwk::SessionInfo>& scnSessionInfo)
1995 {
1996     if (scnSession == nullptr || scnSessionInfo == nullptr) {
1997         return;
1998     }
1999     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2000         NotifyLoadAbility(scnSession->GetCollaboratorType(),
2001             scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
2002         NotifyUpdateSessionInfo(scnSession);
2003         NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2004         scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2005     }
2006 }
2007 
IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)2008 bool SceneSessionManager::IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)
2009 {
2010     bool isPcAppInPad = false;
2011     bool isAppSupportPhoneInPc = false;
2012     auto property = sceneSession->GetSessionProperty();
2013     if (property) {
2014         isPcAppInPad = property->GetIsPcAppInPad();
2015         isAppSupportPhoneInPc = property->GetIsAppSupportPhoneInPc();
2016     }
2017     return (systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || isPcAppInPad;
2018 }
2019 
RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession, const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)2020 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2021     const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2022 {
2023     wptr<SceneSession> weakSceneSession(sceneSession);
2024     auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
2025         auto scnSession = weakSceneSession.promote();
2026         if (scnSession == nullptr) {
2027             TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
2028             return WSError::WS_ERROR_NULLPTR;
2029         }
2030         auto persistentId = scnSession->GetPersistentId();
2031         TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2032             "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2033             persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2034         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2035         scnSession->SetActive(false);
2036 
2037         if (isToDesktop) {
2038             auto info = scnSession->GetSessionInfo();
2039             info.callerToken_ = nullptr;
2040             info.callingTokenId_ = 0;
2041             scnSession->SetSessionInfo(info);
2042         }
2043 
2044         scnSession->BackgroundTask(isSaveSnapshot);
2045         if (!GetSceneSession(persistentId)) {
2046             TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2047             return WSError::WS_ERROR_INVALID_SESSION;
2048         }
2049         if (persistentId == brightnessSessionId_) {
2050             UpdateBrightness(focusedSessionId_);
2051         }
2052         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2053         if (!scnSessionInfo) {
2054             TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2055             return WSError::WS_ERROR_NULLPTR;
2056         }
2057         if (IsPcSceneSessionLifecycle(scnSession)) {
2058             TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2059             scnSession->NotifySessionBackground(1, true, true);
2060         } else {
2061             TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2062                 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2063             if (!isDelegator) {
2064                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2065             } else {
2066                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2067             }
2068         }
2069 
2070         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2071             auto sessionInfo = scnSession->GetSessionInfo();
2072             WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2073         }
2074         return WSError::WS_OK;
2075     };
2076     std::string taskName = "RequestSceneSessionBackground:PID:" +
2077         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2078     taskScheduler_->PostAsyncTask(task, taskName);
2079     return WSError::WS_OK;
2080 }
2081 
NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)2082 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2083 {
2084     wptr<SceneSession> weakSceneSession(sceneSession);
2085     auto task = [this, weakSceneSession, interactive]() {
2086         auto scnSession = weakSceneSession.promote();
2087         if (scnSession == nullptr) {
2088             WLOGFE("session is nullptr");
2089             return;
2090         }
2091         auto persistentId = scnSession->GetPersistentId();
2092         WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2093         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2094         if (!GetSceneSession(persistentId)) {
2095             WLOGFE("session is invalid with %{public}d", persistentId);
2096             return;
2097         }
2098         scnSession->NotifyForegroundInteractiveStatus(interactive);
2099     };
2100 
2101     taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2102 }
2103 
DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)2104 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2105 {
2106     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2107     if (scnSession == nullptr) {
2108         TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2109         return WSError::WS_ERROR_NULLPTR;
2110     }
2111     if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2112         TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2113         auto dialogVec = scnSession->GetDialogVector();
2114         for (auto dialog : dialogVec) {
2115             if (dialog == nullptr) {
2116                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2117                 continue;
2118             }
2119             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2120             if (sceneSession == nullptr) {
2121                 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2122                 return WSError::WS_ERROR_INVALID_SESSION;
2123             }
2124             WindowDestroyNotifyVisibility(sceneSession);
2125             dialog->NotifyDestroy();
2126             dialog->Disconnect();
2127 
2128             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2129             if (dialogSceneSession != nullptr) {
2130                 dialogSceneSession->ClearSpecificSessionCbMap();
2131             }
2132             {
2133                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2134                 EraseSceneSessionAndMarkDirtyLockFree(dialog->GetPersistentId());
2135                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2136                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2137             }
2138         }
2139         scnSession->ClearDialogVector();
2140         return WSError::WS_OK;
2141     }
2142     return WSError::WS_ERROR_INVALID_SESSION;
2143 }
2144 
DestroySubSession(const sptr<SceneSession>& sceneSession)2145 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2146 {
2147     if (sceneSession == nullptr) {
2148         WLOGFW("sceneSession is nullptr");
2149         return;
2150     }
2151     for (const auto& elem : sceneSession->GetSubSession()) {
2152         if (elem != nullptr) {
2153             const auto& persistentId = elem->GetPersistentId();
2154             TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2155             DestroyAndDisconnectSpecificSessionInner(persistentId);
2156         }
2157     }
2158 }
2159 
DestroyToastSession(const sptr<SceneSession>& sceneSession)2160 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2161 {
2162     if (sceneSession == nullptr) {
2163         TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2164         return;
2165     }
2166     for (const auto& elem : sceneSession->GetToastSession()) {
2167         if (elem != nullptr) {
2168             const auto& persistentId = elem->GetPersistentId();
2169             TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2170             DestroyAndDisconnectSpecificSessionInner(persistentId);
2171         }
2172     }
2173 }
2174 
EraseSceneSessionMapById(int32_t persistentId)2175 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2176 {
2177     auto sceneSession = GetSceneSession(persistentId);
2178     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2179     EraseSceneSessionAndMarkDirtyLockFree(persistentId);
2180     systemTopSceneSessionMap_.erase(persistentId);
2181     nonSystemFloatSceneSessionMap_.erase(persistentId);
2182     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2183         MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2184         MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
2185     }
2186 }
2187 
2188 /**
2189  * if visible session is erased, mark dirty
2190  * lock-free
2191  */
EraseSceneSessionAndMarkDirtyLockFree(int32_t persistentId)2192 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLockFree(int32_t persistentId)
2193 {
2194     // get scene session lock-free
2195     auto iter = sceneSessionMap_.find(persistentId);
2196     if (iter == sceneSessionMap_.end()) {
2197         TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2198         return;
2199     }
2200     sptr<SceneSession> sceneSession = iter->second;
2201 
2202     if (sceneSession != nullptr && sceneSession->IsVisible()) {
2203         sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2204     }
2205     sceneSessionMap_.erase(persistentId);
2206 }
2207 
RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession, bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)2208 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2209     bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2210 {
2211     auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2212         needRemoveSession, isSaveSnapshot, isForceClean]() {
2213         auto scnSession = weakSceneSession.promote();
2214         if (scnSession == nullptr) {
2215             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2216             return WSError::WS_ERROR_NULLPTR;
2217         }
2218         auto persistentId = scnSession->GetPersistentId();
2219         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2220         RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2221         lastUpdatedAvoidArea_.erase(persistentId);
2222         DestroyDialogWithMainWindow(scnSession);
2223         DestroyToastSession(scnSession);
2224         DestroySubSession(scnSession); // destroy sub session by destruction
2225         TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2226             " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2227         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2228         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2229             auto sessionInfo = scnSession->GetSessionInfo();
2230             WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sessionInfo.bundleName_);
2231         }
2232         WindowDestroyNotifyVisibility(scnSession);
2233         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2234         scnSession->DisconnectTask(false, isSaveSnapshot);
2235         if (!GetSceneSession(persistentId)) {
2236             TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2237             return WSError::WS_ERROR_INVALID_SESSION;
2238         }
2239         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2240         if (!scnSessionInfo) {
2241             return WSError::WS_ERROR_NULLPTR;
2242         }
2243         scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2244         if (scnSessionInfo->resultCode == -1) {
2245             OHOS::AAFwk::Want want;
2246             scnSessionInfo->want = want;
2247         }
2248         return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2249     };
2250     std::string taskName = "RequestSceneSessionDestruction:PID:" +
2251         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2252     taskScheduler_->PostAsyncTask(task, taskName);
2253     return WSError::WS_OK;
2254 }
2255 
ResetWantInfo(const sptr<SceneSession>& sceneSession)2256 void SceneSessionManager::ResetWantInfo(const sptr<SceneSession>& sceneSession)
2257 {
2258     auto& sessionInfo = sceneSession->GetSessionInfo();
2259     if (sessionInfo.want != nullptr) {
2260         const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2261         const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2262         const auto& keySessionId = sessionInfo.want->GetStringParam(KEY_SESSION_ID);
2263         auto want = std::make_shared<AAFwk::Want>();
2264         AppExecFwk::ElementName element;
2265         element.SetBundleName(bundleName);
2266         element.SetAbilityName(abilityName);
2267         want->SetElement(element);
2268         want->SetBundle(bundleName);
2269         if (!keySessionId.empty()) {
2270             want->SetParam(KEY_SESSION_ID, keySessionId);
2271         }
2272         sceneSession->SetSessionInfoWant(want);
2273     }
2274 }
2275 
RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession, sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)2276 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession,
2277     sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2278 {
2279     auto persistentId = sceneSession->GetPersistentId();
2280     TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}d",
2281         persistentId, sceneSession->GetSessionInfo().isSystem_);
2282     if (isForceClean) {
2283         AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2284     } else {
2285         AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2286     }
2287     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2288     if (needRemoveSession) {
2289         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2290             NotifyClearSession(sceneSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2291         }
2292         EraseSceneSessionMapById(persistentId);
2293     } else {
2294         // if terminate, reset want. so start from recent, start a new one.
2295         TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2296         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2297             sceneSession->SetSessionInfoWant(nullptr);
2298         }
2299         ResetWantInfo(sceneSession);
2300         sceneSession->ResetSessionInfoResultCode();
2301     }
2302     NotifySessionForCallback(sceneSession, needRemoveSession);
2303     // Arrive at the STOP task end.
2304     sceneSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2305     // Clear js cb map if needed.
2306     sceneSession->ClearJsSceneSessionCbMap(needRemoveSession);
2307     return WSError::WS_OK;
2308 }
2309 
AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage, const sptr<SceneSession>& sceneSession)2310 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2311     const sptr<SceneSession>& sceneSession)
2312 {
2313     if (sceneSession == nullptr || sessionStage == nullptr) {
2314         TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2315         return;
2316     }
2317 
2318     auto remoteObject = sessionStage->AsObject();
2319     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2320     if (windowDeath_ == nullptr) {
2321         TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2322         return;
2323     }
2324     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2325         TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2326         return;
2327     }
2328     WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2329 }
2330 
DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)2331 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2332 {
2333     auto task = [this, remoteObject]() {
2334         auto iter = remoteObjectMap_.find(remoteObject);
2335         if (iter == remoteObjectMap_.end()) {
2336             WLOGFE("Invalid remoteObject");
2337             return;
2338         }
2339         WLOGFD("Remote died, id: %{public}d", iter->second);
2340         auto sceneSession = GetSceneSession(iter->second);
2341         if (sceneSession == nullptr) {
2342             WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2343             return;
2344         }
2345         DestroyAndDisconnectSpecificSessionInner(iter->second);
2346         remoteObjectMap_.erase(iter);
2347     };
2348     taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2349 }
2350 
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)2351 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2352     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2353     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2354     SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2355 {
2356     if (property == nullptr) {
2357         WLOGFE("property is nullptr");
2358         return WSError::WS_ERROR_NULLPTR;
2359     }
2360 
2361     if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2362         WLOGFE("create system window or modal subwindow permission denied!");
2363         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2364     }
2365 
2366     bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2367                         property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2368     bool isSystemCalling = SessionPermission::IsSystemCalling();
2369     if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2370         auto parentSession = GetSceneSession(property->GetParentPersistentId());
2371         if (parentSession) {
2372             shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2373         }
2374     }
2375     if (shouldBlock) {
2376         TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2377         return WSError::WS_ERROR_INVALID_OPERATION;
2378     }
2379 
2380     if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2381         property->GetIsUIExtFirstSubWindow() && property->GetIsUIExtensionAbilityProcess() &&
2382         SessionPermission::IsStartedByUIExtension()) {
2383         auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2384         if (extensionParentSession == nullptr) {
2385             WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2386             return WSError::WS_ERROR_NULLPTR;
2387         }
2388         SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2389         AAFwk::UIExtensionHostInfo hostInfo;
2390         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2391         if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2392             WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2393                 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2394                 hostInfo.elementName_.GetBundleName().c_str());
2395             return WSError::WS_ERROR_INVALID_WINDOW;
2396         }
2397     }
2398 
2399     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2400     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2401         WLOGFE("The alarm window has been deprecated!");
2402         return WSError::WS_ERROR_INVALID_WINDOW;
2403     }
2404 
2405     if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2406         WLOGFE("pip window is not enable to create.");
2407         return WSError::WS_DO_NOTHING;
2408     }
2409     TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2410         property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2411 
2412     // Get pid and uid before posting task.
2413     auto pid = IPCSkeleton::GetCallingRealPid();
2414     auto uid = IPCSkeleton::GetCallingUid();
2415     auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2416                     &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2417         if (property == nullptr) {
2418             return WSError::WS_ERROR_NULLPTR;
2419         }
2420         const auto& type = property->GetWindowType();
2421         // create specific session
2422         SessionInfo info;
2423         info.windowType_ = static_cast<uint32_t>(type);
2424         info.bundleName_ = property->GetSessionInfo().bundleName_;
2425         info.abilityName_ = property->GetSessionInfo().abilityName_;
2426         info.moduleName_ = property->GetSessionInfo().moduleName_;
2427 
2428         ClosePipWindowIfExist(type);
2429         sptr<SceneSession> newSession = RequestSceneSession(info, property);
2430         if (newSession == nullptr) {
2431             TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2432             return WSError::WS_ERROR_NULLPTR;
2433         }
2434         property->SetSystemCalling(isSystemCalling);
2435         auto errCode = newSession->ConnectInner(
2436             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2437         newSession->SetIsSystemSpecificSession(isSystemCalling);
2438         systemConfig = systemConfig_;
2439         if (property) {
2440             persistentId = property->GetPersistentId();
2441         }
2442 
2443         NotifyCreateSpecificSession(newSession, property, type);
2444         session = newSession;
2445         AddClientDeathRecipient(sessionStage, newSession);
2446         TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2447             "parentId: %{public}d, type: %{public}d",
2448             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2449         return errCode;
2450     };
2451 
2452     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2453 }
2454 
ClosePipWindowIfExist(WindowType type)2455 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2456 {
2457     if (type != WindowType::WINDOW_TYPE_PIP) {
2458         return;
2459     }
2460     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2461     for (const auto& iter: sceneSessionMap_) {
2462         auto& session = iter.second;
2463         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2464             session->NotifyCloseExistPipWindow();
2465             break;
2466         }
2467     }
2468 }
2469 
CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)2470 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2471 {
2472     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2473     for (const auto& iter: sceneSessionMap_) {
2474         auto& session = iter.second;
2475         if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2476             pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2477             IsSessionVisibleForeground(session)) {
2478             TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2479             return false;
2480         }
2481     }
2482     return true;
2483 }
2484 
isEnablePiPCreate(const sptr<WindowSessionProperty>& property)2485 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2486 {
2487     if (isScreenLocked_) {
2488         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2489         return false;
2490     }
2491     Rect pipRect = property->GetRequestRect();
2492     if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2493         TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2494         return false;
2495     }
2496     if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2497         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2498         return false;
2499     }
2500     auto parentSession = GetSceneSession(property->GetParentPersistentId());
2501     if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2502         TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2503         return false;
2504     }
2505     return true;
2506 }
2507 
CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)2508 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2509 {
2510     WindowType type = property->GetWindowType();
2511     if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
2512         return true;
2513     }
2514 
2515     if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
2516         TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
2517         return false;
2518     }
2519 
2520     if (!SessionPermission::IsSystemCalling()) {
2521         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
2522         return false;
2523     }
2524 
2525     return true;
2526 }
2527 
CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)2528 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
2529 {
2530     WindowType type = property->GetWindowType();
2531     if (WindowHelper::IsUIExtensionWindow(type)) {
2532         // UIExtension window disallowed.
2533         return false;
2534     }
2535     if (!WindowHelper::IsSystemWindow(type)) {
2536         // type is not system
2537         return true;
2538     }
2539     if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) {
2540         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
2541         if (SessionPermission::IsStartedByInputMethod()) {
2542             TLOGD(WmsLogTag::WMS_KEYBOARD, "check permission success, input method app create input method window.");
2543             return true;
2544         } else {
2545             TLOGE(WmsLogTag::WMS_KEYBOARD, "check permission failed.");
2546             return false;
2547         }
2548     }
2549     if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
2550         // some system types could be created by normal app
2551         return true;
2552     }
2553     if (type == WindowType::WINDOW_TYPE_FLOAT) {
2554         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
2555         if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
2556             (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd() ||
2557             systemConfig_.supportTypeFloatWindow_)) {
2558             WLOGFI("check float permission success.");
2559             return true;
2560         } else {
2561             WLOGFE("check float permission failed.");
2562             return false;
2563         }
2564     }
2565     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
2566         WLOGFD("check create permission success, create with system calling.");
2567         return true;
2568     }
2569     WLOGFE("check system window permission failed.");
2570     return false;
2571 }
2572 
RecoverSessionInfo(const sptr<WindowSessionProperty>& property)2573 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
2574 {
2575     SessionInfo sessionInfo;
2576     if (property == nullptr) {
2577         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2578         return sessionInfo;
2579     }
2580     sessionInfo = property->GetSessionInfo();
2581     sessionInfo.persistentId_ = property->GetPersistentId();
2582     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
2583     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
2584     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
2585     sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
2586                                     ? SessionState::STATE_ACTIVE
2587                                     : SessionState::STATE_BACKGROUND;
2588     sessionInfo.isPersistentRecover_ = true;
2589     sessionInfo.appInstanceKey_ = property->GetAppInstanceKey();
2590     TLOGI(WmsLogTag::WMS_RECOVER,
2591         "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
2592         "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
2593         "windowState=%{public}u, appInstanceKey=%{public}s",
2594         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2595         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_,
2596         sessionInfo.appInstanceKey_.c_str());
2597     return sessionInfo;
2598 }
2599 
SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)2600 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
2601 {
2602     TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
2603            "%{public}d", alivePersistentIds.size(), currentUserId_);
2604     alivePersistentIds_ = alivePersistentIds;
2605 }
2606 
IsNeedRecover(const int32_t persistentId)2607 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
2608 {
2609     auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
2610     if (it == alivePersistentIds_.end()) {
2611         TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
2612         return false;
2613     }
2614     return true;
2615 }
2616 
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property, bool isSpecificSession)2617 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
2618     bool isSpecificSession)
2619 {
2620     if (property == nullptr) {
2621         TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2622         return WSError::WS_ERROR_NULLPTR;
2623     }
2624     if (!CheckSystemWindowPermission(property)) {
2625         TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
2626         return WSError::WS_ERROR_NOT_SYSTEM_APP;
2627     }
2628     if (isSpecificSession) {
2629         if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
2630             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2631             return WSError::WS_ERROR_INVALID_PARAM;
2632         }
2633     } else {
2634         if (!IsNeedRecover(property->GetPersistentId())) {
2635             TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2636             return WSError::WS_ERROR_INVALID_PARAM;
2637         }
2638     }
2639     return WSError::WS_OK;
2640 }
2641 
RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)2642 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2643     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2644     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
2645 {
2646     auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
2647     if (propCheckRet != WSError::WS_OK) {
2648         return propCheckRet;
2649     }
2650     auto pid = IPCSkeleton::GetCallingRealPid();
2651     auto uid = IPCSkeleton::GetCallingUid();
2652     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
2653         if (recoveringFinished_) {
2654             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2655             return WSError::WS_ERROR_INVALID_OPERATION;
2656         }
2657         // recover specific session
2658         SessionInfo info = RecoverSessionInfo(property);
2659         TLOGI(WmsLogTag::WMS_RECOVER, "callingSessionId = %{public}" PRIu32, property->GetCallingSessionId());
2660         ClosePipWindowIfExist(property->GetWindowType());
2661         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
2662         if (sceneSession == nullptr) {
2663             TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
2664             return WSError::WS_ERROR_NULLPTR;
2665         }
2666 
2667         auto persistentId = sceneSession->GetPersistentId();
2668         if (persistentId != info.persistentId_) {
2669             TLOGE(WmsLogTag::WMS_RECOVER,
2670                 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
2671                 info.persistentId_, persistentId, property->GetParentPersistentId());
2672             failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
2673             EraseSceneSessionMapById(persistentId);
2674             return WSError::WS_ERROR_INVALID_SESSION;
2675         }
2676 
2677         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2678         if (errCode != WSError::WS_OK) {
2679             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
2680             EraseSceneSessionMapById(persistentId);
2681             return errCode;
2682         }
2683         NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
2684         CacheSubSessionForRecovering(sceneSession, property);
2685         NotifySessionUnfocusedToClient(persistentId);
2686         AddClientDeathRecipient(sessionStage, sceneSession);
2687         session = sceneSession;
2688         return errCode;
2689     };
2690     return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
2691 }
2692 
NotifyRecoveringFinished()2693 void SceneSessionManager::NotifyRecoveringFinished()
2694 {
2695     taskScheduler_->PostAsyncTask([this]() {
2696             TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
2697             recoveringFinished_ = true;
2698             recoverSubSessionCacheMap_.clear();
2699         }, "NotifyRecoveringFinished");
2700 }
2701 
CacheSubSessionForRecovering( sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)2702 void SceneSessionManager::CacheSubSessionForRecovering(
2703     sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
2704 {
2705     if (recoveringFinished_) {
2706         TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
2707         return;
2708     }
2709 
2710     if (sceneSession == nullptr || property == nullptr) {
2711         TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
2712         return;
2713     }
2714 
2715     auto windowType = property->GetWindowType();
2716     if (!SessionHelper::IsSubWindow(windowType)) {
2717         return;
2718     }
2719 
2720     auto persistentId = property->GetParentPersistentId();
2721     if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
2722         return;
2723     }
2724 
2725     TLOGI(WmsLogTag::WMS_RECOVER,
2726         "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
2727         sceneSession->GetPersistentId(), persistentId);
2728 
2729     if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
2730         recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
2731     } else {
2732         recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
2733     }
2734 }
2735 
RecoverCachedSubSession(int32_t persistentId)2736 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
2737 {
2738     auto iter = recoverSubSessionCacheMap_.find(persistentId);
2739     if (iter == recoverSubSessionCacheMap_.end()) {
2740         return;
2741     }
2742 
2743     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
2744     for (auto& sceneSession : iter->second) {
2745         NotifyCreateSubSession(persistentId, sceneSession);
2746     }
2747     recoverSubSessionCacheMap_.erase(iter);
2748 }
2749 
NotifySessionUnfocusedToClient(int32_t persistentId)2750 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
2751 {
2752     TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
2753     listenerController_->NotifySessionUnfocused(persistentId);
2754 }
2755 
RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)2756 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
2757     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2758     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
2759 {
2760     auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
2761     if (propCheckRet != WSError::WS_OK) {
2762         return propCheckRet;
2763     }
2764     auto pid = IPCSkeleton::GetCallingRealPid();
2765     auto uid = IPCSkeleton::GetCallingUid();
2766     auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
2767         if (recoveringFinished_) {
2768             TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2769             return WSError::WS_ERROR_INVALID_OPERATION;
2770         }
2771         if (recoverSceneSessionFunc_ == nullptr) {
2772             TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
2773             return WSError::WS_ERROR_NULLPTR;
2774         }
2775         SessionInfo sessionInfo = RecoverSessionInfo(property);
2776         sptr<SceneSession> sceneSession = nullptr;
2777         if (SessionHelper::IsMainWindow(property->GetWindowType())) {
2778             sceneSession = RequestSceneSession(sessionInfo, nullptr);
2779         } else {
2780             sceneSession = RequestSceneSession(sessionInfo, property);
2781         }
2782         if (sceneSession == nullptr) {
2783             TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
2784             return WSError::WS_ERROR_NULLPTR;
2785         }
2786         int32_t persistentId = sceneSession->GetPersistentId();
2787         if (persistentId != sessionInfo.persistentId_) {
2788             TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
2789                 sessionInfo.persistentId_, persistentId);
2790             EraseSceneSessionMapById(persistentId);
2791             return WSError::WS_ERROR_INVALID_SESSION;
2792         }
2793         auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2794         if (ret != WSError::WS_OK) {
2795             TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
2796             EraseSceneSessionMapById(sessionInfo.persistentId_);
2797             return ret;
2798         }
2799         sceneSession->SetRecovered(true);
2800         recoverSceneSessionFunc_(sceneSession, sessionInfo);
2801         NotifySessionUnfocusedToClient(persistentId);
2802         session = sceneSession;
2803         return WSError::WS_OK;
2804     };
2805     return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
2806 }
2807 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)2808 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
2809 {
2810     TLOGI(WmsLogTag::WMS_RECOVER, "called");
2811     recoverSceneSessionFunc_ = func;
2812 }
2813 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)2814 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
2815 {
2816     createSystemSessionFunc_ = func;
2817 }
2818 
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)2819 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
2820 {
2821     createKeyboardSessionFunc_ = func;
2822 }
2823 
RegisterCreateSubSessionListener(int32_t persistentId, const NotifyCreateSubSessionFunc& func)2824 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
2825     const NotifyCreateSubSessionFunc& func)
2826 {
2827     TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
2828     auto task = [this, persistentId, func]() {
2829         createSubSessionFuncMap_[persistentId] = func;
2830         RecoverCachedSubSession(persistentId);
2831         return WMError::WM_OK;
2832     };
2833     taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
2834 }
2835 
NotifyCreateSpecificSession(sptr<SceneSession> newSession, sptr<WindowSessionProperty> property, const WindowType& type)2836 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
2837     sptr<WindowSessionProperty> property, const WindowType& type)
2838 {
2839     if (newSession == nullptr) {
2840         WLOGFE("newSession is nullptr");
2841         return;
2842     }
2843     if (property == nullptr) {
2844         WLOGFE("property is nullptr");
2845         return;
2846     }
2847     if (SessionHelper::IsSystemWindow(type)) {
2848         if (type == WindowType::WINDOW_TYPE_FLOAT) {
2849             auto parentSession = GetSceneSession(property->GetParentPersistentId());
2850             if (parentSession != nullptr) {
2851                 newSession->SetParentSession(parentSession);
2852             }
2853         }
2854         if (type == WindowType::WINDOW_TYPE_TOAST) {
2855             NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
2856         }
2857         if (type != WindowType::WINDOW_TYPE_DIALOG) {
2858             if (WindowHelper::IsSystemSubWindow(type)) {
2859                 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2860             } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
2861                 && createKeyboardSessionFunc_) {
2862                 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
2863             } else if (createSystemSessionFunc_) {
2864                 createSystemSessionFunc_(newSession);
2865             }
2866             TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
2867                 newSession->GetPersistentId(), type);
2868         } else {
2869             TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, "
2870                 "type:%{public}d", newSession->GetPersistentId(), type);
2871             return;
2872         }
2873     } else if (SessionHelper::IsSubWindow(type)) {
2874         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2875         TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
2876             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
2877     } else {
2878         TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
2879             newSession->GetPersistentId(), type);
2880     }
2881 }
2882 
NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)2883 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
2884 {
2885     if (session == nullptr) {
2886         TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
2887         return;
2888     }
2889     auto iter = createSubSessionFuncMap_.find(persistentId);
2890     if (iter == createSubSessionFuncMap_.end()) {
2891         TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
2892         return;
2893     }
2894 
2895     sptr<SceneSession> parentSession = nullptr;
2896     if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
2897         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2898         parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
2899     } else {
2900         parentSession = GetSceneSession(persistentId);
2901     }
2902     if (parentSession == nullptr) {
2903         TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
2904             persistentId, session->GetPersistentId());
2905         return;
2906     }
2907     parentSession->AddSubSession(session);
2908     session->SetParentSession(parentSession);
2909     if (iter->second) {
2910         iter->second(session);
2911     }
2912     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
2913         persistentId, session->GetPersistentId());
2914 }
2915 
GetMainParentSceneSession(int32_t persistentId, const std::map<int32_t, sptr<SceneSession>>& sessionMap)2916 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
2917     const std::map<int32_t, sptr<SceneSession>>& sessionMap)
2918 {
2919     if (persistentId == INVALID_SESSION_ID) {
2920         TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
2921         return nullptr;
2922     }
2923     auto iter = sessionMap.find(persistentId);
2924     if (iter == sessionMap.end()) {
2925         WLOGFD("Error found scene session with id: %{public}d", persistentId);
2926         return nullptr;
2927     }
2928     sptr<SceneSession> parentSession = iter->second;
2929     if (parentSession == nullptr) {
2930         TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
2931         return nullptr;
2932     }
2933     bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
2934         parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
2935     if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
2936         TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
2937         return parentSession;
2938     }
2939     return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
2940 }
2941 
NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)2942 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
2943 {
2944     if (session == nullptr) {
2945         TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
2946         return;
2947     }
2948 
2949     auto parentSession = GetSceneSession(persistentId);
2950     if (parentSession == nullptr) {
2951         TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
2952             persistentId, session->GetPersistentId());
2953         return;
2954     }
2955     parentSession->AddToastSession(session);
2956     session->SetParentSession(parentSession);
2957     TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
2958         persistentId, session->GetPersistentId());
2959 }
2960 
UnregisterCreateSubSessionListener(int32_t persistentId)2961 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
2962 {
2963     TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
2964     auto task = [this, persistentId]() {
2965         auto iter = createSubSessionFuncMap_.find(persistentId);
2966         if (iter != createSubSessionFuncMap_.end()) {
2967             createSubSessionFuncMap_.erase(persistentId);
2968         } else {
2969             TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
2970         }
2971         return WMError::WM_OK;
2972     };
2973     taskScheduler_->PostSyncTask(task);
2974 }
2975 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)2976 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
2977 {
2978     WLOGFD("SetStatusBarEnabledChangeListener");
2979     if (!func) {
2980         WLOGFD("set func is null");
2981     }
2982     statusBarEnabledChangeFunc_ = func;
2983 }
2984 
SetGestureNavigationEnabledChangeListener( const ProcessGestureNavigationEnabledChangeFunc& func)2985 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
2986     const ProcessGestureNavigationEnabledChangeFunc& func)
2987 {
2988     WLOGFD("SetGestureNavigationEnabledChangeListener");
2989     if (!func) {
2990         WLOGFD("set func is null");
2991     }
2992     gestureNavigationEnabledChangeFunc_ = func;
2993 }
2994 
OnOutsideDownEvent(int32_t x, int32_t y)2995 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
2996 {
2997     TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
2998     if (outsideDownEventFunc_) {
2999         outsideDownEventFunc_(x, y);
3000     }
3001 }
3002 
NotifySessionTouchOutside(int32_t persistentId)3003 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
3004 {
3005     auto task = [this, persistentId]() {
3006         int32_t callingSessionId = INVALID_WINDOW_ID;
3007         auto sceneSession = GetSceneSession(persistentId);
3008         if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3009             callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
3010             TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
3011                 persistentId, callingSessionId);
3012         }
3013         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3014         for (const auto &item : sceneSessionMap_) {
3015             sceneSession = item.second;
3016             if (sceneSession == nullptr) {
3017                 continue;
3018             }
3019             if (!(sceneSession->IsVisible() ||
3020                 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3021                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
3022                 continue;
3023             }
3024             auto sessionId = sceneSession->GetPersistentId();
3025             if ((!sceneSession->CheckOutTouchOutsideRegister()) &&
3026                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3027                 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3028                 continue;
3029             }
3030             if (sessionId == callingSessionId || sessionId == persistentId) {
3031                 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3032                 continue;
3033             }
3034             sceneSession->NotifyTouchOutside();
3035         }
3036     };
3037 
3038     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3039     return;
3040 }
3041 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)3042 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3043 {
3044     WLOGFD("SetOutsideDownEventListener");
3045     outsideDownEventFunc_ = func;
3046 }
3047 
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3048 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3049 {
3050     auto sceneSession = GetSceneSession(persistentId);
3051     if (sceneSession == nullptr) {
3052         return WSError::WS_ERROR_NULLPTR;
3053     }
3054     auto ret = sceneSession->UpdateActiveStatus(false);
3055     WindowDestroyNotifyVisibility(sceneSession);
3056     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
3057         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3058         if (parentSession == nullptr) {
3059             TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3060         } else {
3061             parentSession->RemoveDialogToParentSession(sceneSession);
3062         }
3063     }
3064     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_TOAST) {
3065         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3066         if (parentSession != nullptr) {
3067             TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3068             parentSession->RemoveToastSession(persistentId);
3069         } else {
3070             TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3071         }
3072     }
3073     ret = sceneSession->Disconnect();
3074     sceneSession->ClearSpecificSessionCbMap();
3075     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3076         DestroySubSession(sceneSession);
3077         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3078         if (parentSession != nullptr) {
3079             TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3080             parentSession->RemoveSubSession(persistentId);
3081         } else {
3082             TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3083         }
3084         DestroyUIServiceExtensionSubWindow(sceneSession);
3085     }
3086     {
3087         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3088         EraseSceneSessionAndMarkDirtyLockFree(persistentId);
3089         systemTopSceneSessionMap_.erase(persistentId);
3090         nonSystemFloatSceneSessionMap_.erase(persistentId);
3091         UnregisterCreateSubSessionListener(persistentId);
3092     }
3093     TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3094     return ret;
3095 }
3096 
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3097 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3098 {
3099     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3100     auto task = [this, persistentId, callingPid]() {
3101         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3102         auto sceneSession = GetSceneSession(persistentId);
3103         if (sceneSession == nullptr) {
3104             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3105             return WSError::WS_ERROR_NULLPTR;
3106         }
3107 
3108         if (callingPid != sceneSession->GetCallingPid()) {
3109             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3110             return WSError::WS_ERROR_INVALID_PERMISSION;
3111         }
3112         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3113     };
3114 
3115     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3116 }
3117 
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId, const sptr<IRemoteObject>& callback)3118 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3119     const sptr<IRemoteObject>& callback)
3120 {
3121     if (callback == nullptr) {
3122         return WSError::WS_ERROR_NULLPTR;
3123     }
3124     const auto callingPid = IPCSkeleton::GetCallingRealPid();
3125     auto task = [this, persistentId, callingPid, callback]() {
3126         TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3127         auto sceneSession = GetSceneSession(persistentId);
3128         if (sceneSession == nullptr) {
3129             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3130             return WSError::WS_ERROR_NULLPTR;
3131         }
3132 
3133         if (callingPid != sceneSession->GetCallingPid()) {
3134             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3135             return WSError::WS_ERROR_INVALID_PERMISSION;
3136         }
3137         sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3138         return DestroyAndDisconnectSpecificSessionInner(persistentId);
3139     };
3140 
3141     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3142 }
3143 
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)3144 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
3145 {
3146     if (!sceneSession) {
3147         TLOGE(WmsLogTag::WMS_SUB,"sceneSession is null");
3148         return;
3149     }
3150     auto sessionProperty = sceneSession->GetSessionProperty();
3151     if (sessionProperty && sessionProperty->GetIsUIExtFirstSubWindow() &&
3152         !sessionProperty->GetIsUIExtensionAbilityProcess()) {
3153         sceneSession->NotifyDestroy();
3154         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
3155             TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
3156         TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
3157             sceneSession->GetPersistentId(), errCode);
3158     }
3159 }
3160 
GetWindowSceneConfig() const3161 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3162 {
3163     return appWindowSceneConfig_;
3164 }
3165 
UpdateRotateAnimationConfig(const RotateAnimationConfig& config)3166 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3167 {
3168     auto task = [this, config] {
3169         TLOGNI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3170         rotateAnimationConfig_.duration_ = config.duration_;
3171     };
3172     taskScheduler_->PostAsyncTask(task, __func__);
3173 }
3174 
ProcessBackEvent()3175 WSError SceneSessionManager::ProcessBackEvent()
3176 {
3177     auto task = [this]() {
3178         auto session = GetSceneSession(focusedSessionId_);
3179         if (!session) {
3180             WLOGFE("session is nullptr: %{public}d", focusedSessionId_);
3181             return WSError::WS_ERROR_INVALID_SESSION;
3182         }
3183         WLOGFI("ProcessBackEvent session persistentId:%{public}d needBlock::%{public}d",
3184             focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3185         if (needBlockNotifyFocusStatusUntilForeground_) {
3186             WLOGFD("RequestSessionBack when start session");
3187             if (session->GetSessionInfo().abilityInfo != nullptr &&
3188                 session->GetSessionInfo().abilityInfo->unclearableMission) {
3189                 TLOGI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3190                 return WSError::WS_OK;
3191             }
3192             session->RequestSessionBack(false);
3193             return WSError::WS_OK;
3194         }
3195         if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3196             rootSceneProcessBackEventFunc_();
3197         } else {
3198             session->ProcessBackEvent();
3199         }
3200         return WSError::WS_OK;
3201     };
3202 
3203     taskScheduler_->PostAsyncTask(task, "ProcessBackEvent");
3204     return WSError::WS_OK;
3205 }
3206 
InitUserInfo(int32_t userId, std::string& fileDir)3207 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3208 {
3209     if (userId == DEFAULT_USERID || fileDir.empty()) {
3210         TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3211         return WSError::WS_DO_NOTHING;
3212     }
3213     TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3214     auto task = [this, userId, &fileDir]() {
3215         if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3216             TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3217         }
3218         if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3219             TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3220         }
3221         currentUserId_ = userId;
3222         SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3223         if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
3224             MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
3225         }
3226         RegisterSecSurfaceInfoListener();
3227         return WSError::WS_OK;
3228     };
3229     return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3230 }
3231 
IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)3232 bool SceneSessionManager::IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)
3233 {
3234     auto sessionState = sceneSession->GetSessionState();
3235     auto isInvalidMainSession = !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
3236                                 sessionState == SessionState::STATE_DISCONNECT ||
3237                                 sessionState == SessionState::STATE_END;
3238     if (isInvalidMainSession) {
3239         TLOGD(WmsLogTag::WMS_MULTI_USER, "persistentId: %{public}d, type: %{public}d, state: %{public}d",
3240             sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState());
3241     }
3242     return sceneSession->GetCallingPid() != pid && IsPcSceneSessionLifecycle(sceneSession) && !isInvalidMainSession;
3243 }
3244 
StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)3245 WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)
3246 {
3247     auto persistentId = sceneSession->GetPersistentId();
3248     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3249     if (!abilitySessionInfo) {
3250         TLOGE(WmsLogTag::WMS_MULTI_USER, "Create Ability info failed, id %{public}d", persistentId);
3251         return WSError::WS_ERROR_NULLPTR;
3252     }
3253     if (!isUserActive) {
3254         TLOGI(WmsLogTag::WMS_MULTI_USER,
3255             "MinimizeUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
3256             sceneSession->GetWindowType(), sceneSession->GetSessionState());
3257         bool isFromUser = false;
3258         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(
3259             abilitySessionInfo, isFromUser, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
3260         if (errCode == ERR_OK) {
3261             sceneSession->SetMinimizedFlagByUserSwitch(true);
3262         } else {
3263             TLOGE(WmsLogTag::WMS_MULTI_USER, "minimize failed! errCode: %{public}d", errCode);
3264         }
3265     } else if (sceneSession->IsMinimizedByUserSwitch()) {
3266         TLOGI(WmsLogTag::WMS_MULTI_USER,
3267             "StartUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
3268             sceneSession->GetWindowType(), sceneSession->GetSessionState());
3269         sceneSession->SetMinimizedFlagByUserSwitch(false);
3270         bool isColdStart = false;
3271         int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(
3272             abilitySessionInfo, isColdStart, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
3273         if (errCode != ERR_OK) {
3274             TLOGE(WmsLogTag::WMS_MULTI_USER, "start failed! errCode: %{public}d", errCode);
3275             sceneSession->NotifySessionExceptionInner(abilitySessionInfo, true);
3276             if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
3277                 startUIAbilityErrorFunc_(
3278                     static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
3279             }
3280         }
3281     }
3282     return WSError::WS_OK;
3283 }
3284 
NotifySwitchingUser(const bool isUserActive)3285 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3286 {
3287     const char* const where = __func__;
3288     auto task = [this, isUserActive, where]() {
3289         TLOGNI(WmsLogTag::WMS_MULTI_USER, "%{public}s: IsUserActive=%{public}u, currentUserId=%{public}d", where,
3290             isUserActive, currentUserId_);
3291         isUserBackground_ = !isUserActive;
3292         SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3293         if (isUserActive) { // switch to current user
3294             SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3295             if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
3296                 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
3297             }
3298             // notify screenSessionManager to recover current user
3299             ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3300             FlushWindowInfoToMMI(true);
3301             NotifyAllAccessibilityInfo();
3302         } else { // switch to another user
3303             SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3304         }
3305 
3306         // Change app life cycle in pc when user switch, do app freeze
3307         int32_t pid = GetPid();
3308         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3309         for (const auto& [_, sceneSession] : sceneSessionMap_) {
3310             if (sceneSession == nullptr) {
3311                 TLOGNE(WmsLogTag::WMS_MULTI_USER, "%{public}s: session is null", where);
3312                 continue;
3313             }
3314             if (IsNeedChangeLifeCycleOnUserSwitch(sceneSession, pid)) {
3315                 StartOrMinimizeUIAbilityBySCB(sceneSession, isUserActive);
3316             }
3317         }
3318         return WSError::WS_OK;
3319     };
3320     taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3321 }
3322 
GetBundleManager()3323 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3324 {
3325     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3326     if (systemAbilityMgr == nullptr) {
3327         WLOGFE("Failed to get SystemAbilityManager.");
3328         return nullptr;
3329     }
3330 
3331     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3332     if (bmsObj == nullptr) {
3333         WLOGFE("Failed to get BundleManagerService.");
3334         return nullptr;
3335     }
3336 
3337     return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3338 }
3339 
GetResourceManager( const AppExecFwk::AbilityInfo& abilityInfo)3340 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3341     const AppExecFwk::AbilityInfo& abilityInfo)
3342 {
3343     auto context = rootSceneContextWeak_.lock();
3344     if (!context) {
3345         WLOGFE("context is nullptr.");
3346         return nullptr;
3347     }
3348     auto resourceMgr = context->GetResourceManager();
3349     if (!resourceMgr) {
3350         WLOGFE("resourceMgr is nullptr.");
3351         return nullptr;
3352     }
3353     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3354     if (!resConfig) {
3355         WLOGFE("resConfig is nullptr.");
3356         return nullptr;
3357     }
3358     resourceMgr->GetResConfig(*resConfig);
3359     resourceMgr = Global::Resource::CreateResourceManager(
3360         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3361     if (!resourceMgr) {
3362         WLOGFE("resourceMgr is nullptr.");
3363         return nullptr;
3364     }
3365     resourceMgr->UpdateResConfig(*resConfig);
3366 
3367     std::string loadPath;
3368     if (!abilityInfo.hapPath.empty()) { // zipped hap
3369         loadPath = abilityInfo.hapPath;
3370     } else {
3371         loadPath = abilityInfo.resourcePath;
3372     }
3373 
3374     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3375         WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3376     }
3377     return resourceMgr;
3378 }
3379 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo, std::string& path, uint32_t& bgColor)3380 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3381     std::string& path, uint32_t& bgColor)
3382 {
3383     auto resourceMgr = GetResourceManager(abilityInfo);
3384     if (!resourceMgr) {
3385         WLOGFE("resourceMgr is nullptr.");
3386         return false;
3387     }
3388 
3389     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3390         WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3391         return false;
3392     }
3393 
3394     if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3395         WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3396         return false;
3397     }
3398 
3399     if (!abilityInfo.hapPath.empty()) { // zipped hap
3400         auto pos = path.find_last_of('.');
3401         if (pos == std::string::npos) {
3402             WLOGFE("Format error, path %{private}s.", path.c_str());
3403             return false;
3404         }
3405         path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3406     }
3407     return true;
3408 }
3409 
GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)3410 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3411 {
3412     if (!bundleMgr_) {
3413         WLOGFE("bundleMgr_ is nullptr.");
3414         return;
3415     }
3416     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3417     if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3418         WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3419         return;
3420     }
3421     AAFwk::Want want;
3422     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3423     AppExecFwk::AbilityInfo abilityInfo;
3424     if (!bundleMgr_->QueryAbilityInfo(
3425         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3426         WLOGFE("Get ability info from BMS failed!");
3427         return;
3428     }
3429 
3430     if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3431         CacheStartingWindowInfo(abilityInfo, path, bgColor);
3432     }
3433     WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3434         abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3435 }
3436 
GetStartingWindowInfoFromCache( const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)3437 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3438     const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3439 {
3440     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3441     std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3442     auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3443     if (iter == startingWindowMap_.end()) {
3444         return false;
3445     }
3446     auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3447     const auto& infoMap = iter->second;
3448     auto infoMapIter = infoMap.find(key);
3449     if (infoMapIter == infoMap.end()) {
3450         return false;
3451     }
3452     path = infoMapIter->second.startingWindowIconPath_;
3453     bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3454     return true;
3455 }
3456 
CacheStartingWindowInfo( const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)3457 void SceneSessionManager::CacheStartingWindowInfo(
3458     const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3459 {
3460     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3461     auto key = abilityInfo.moduleName + abilityInfo.name;
3462     StartingWindowInfo info = {
3463         .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3464         .startingWindowIconId_ = abilityInfo.startWindowIconId,
3465         .startingWindowBackgroundColor_ = bgColor,
3466         .startingWindowIconPath_ = path,
3467     };
3468     std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3469     auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3470     if (iter != startingWindowMap_.end()) {
3471         auto& infoMap = iter->second;
3472         infoMap.emplace(key, info);
3473         return;
3474     }
3475     if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3476         startingWindowMap_.erase(startingWindowMap_.begin());
3477     }
3478     std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3479     startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3480 }
3481 
OnBundleUpdated(const std::string& bundleName, int userId)3482 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3483 {
3484     taskScheduler_->PostAsyncTask([this, bundleName]() {
3485         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3486         auto iter = startingWindowMap_.find(bundleName);
3487         if (iter != startingWindowMap_.end()) {
3488             startingWindowMap_.erase(iter);
3489         }
3490     },
3491         "OnBundleUpdated");
3492 }
3493 
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)3494 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3495 {
3496     taskScheduler_->PostAsyncTask([this]() {
3497         std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3498         startingWindowMap_.clear();
3499     },
3500         "OnConfigurationUpdated");
3501 }
3502 
FillSessionInfo(sptr<SceneSession>& sceneSession)3503 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3504 {
3505     auto sessionInfo = sceneSession->GetSessionInfo();
3506     if (sessionInfo.bundleName_.empty()) {
3507         WLOGFE("bundleName_ is empty");
3508         return;
3509     }
3510     if (sessionInfo.isSystem_) {
3511         WLOGFD("is system scene!");
3512         return;
3513     }
3514     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3515         sessionInfo.moduleName_);
3516     if (abilityInfo == nullptr) {
3517         WLOGFE("abilityInfo is nullptr!");
3518         return;
3519     }
3520     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3521     sceneSession->SetSessionInfoTime(GetCurrentTime());
3522     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3523         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3524     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3525         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3526     }
3527     TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3528         "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3529         abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3530         abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3531 }
3532 
QueryAbilityInfoFromBMS(const int32_t uId, const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)3533 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3534     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3535 {
3536     if (!bundleMgr_) {
3537         TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3538         return nullptr;
3539     }
3540     SessionInfoList list = {
3541         .uid_ = uId, .bundleName_ = bundleName, .abilityName_ = abilityName, .moduleName_ = moduleName
3542     };
3543     if (abilityInfoMap_.count(list)) {
3544         return abilityInfoMap_[list];
3545     }
3546     AAFwk::Want want;
3547     want.SetElementName("", bundleName, abilityName, moduleName);
3548     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3549     if (abilityInfo == nullptr) {
3550         WLOGFE("abilityInfo is nullptr!");
3551         return nullptr;
3552     }
3553     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3554         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3555         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3556     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
3557     if (!ret) {
3558         WLOGFE("Get ability info from BMS failed!");
3559         return nullptr;
3560     }
3561     abilityInfoMap_[list] = abilityInfo;
3562     return abilityInfo;
3563 }
3564 
GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session, uint32_t& topWinId, uint32_t& zOrder)3565 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
3566     uint32_t& topWinId, uint32_t& zOrder)
3567 {
3568     const auto& subVec = session->GetSubSession();
3569     for (const auto& subSession : subVec) {
3570         if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
3571             TLOGW(WmsLogTag::WMS_SUB,
3572                 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
3573             continue;
3574         }
3575         if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3576              subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
3577             subSession->GetZOrder() > zOrder) {
3578             topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
3579             zOrder = subSession->GetZOrder();
3580             TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
3581                 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
3582         }
3583         if (subSession->GetSubSession().size() > 0) {
3584             GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
3585         }
3586     }
3587 }
3588 
3589 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)3590 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
3591 {
3592     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3593     auto task = [this, mainWinId, &topWinId, callingPid]() {
3594         const auto& mainSession = GetSceneSession(mainWinId);
3595         if (mainSession == nullptr) {
3596             return WMError::WM_ERROR_INVALID_WINDOW;
3597         }
3598 
3599         if (callingPid != mainSession->GetCallingPid()) {
3600             WLOGFE("Permission denied, not destroy by the same process");
3601             return WMError::WM_ERROR_INVALID_PERMISSION;
3602         }
3603         uint32_t zOrder = mainSession->GetZOrder();
3604         topWinId = mainWinId;
3605         GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
3606         TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
3607             "zOrder: %{public}d", mainWinId, topWinId, zOrder);
3608         return WMError::WM_OK;
3609     };
3610 
3611     if (!Session::IsScbCoreEnabled()) {
3612         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3613     }
3614     bool postNow = false;
3615     auto mainSession = GetSceneSession(mainWinId);
3616     if (mainSession != nullptr) {
3617         postNow = !(mainSession->GetUIStateDirty());
3618     }
3619     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
3620     if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
3621         taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
3622         return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3623     }
3624     TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
3625     {
3626         std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
3627         if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
3628             std::cv_status::timeout) {
3629             TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
3630         }
3631     }
3632     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3633 }
3634 
GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap, int32_t windowId, int32_t& mainWindowId)3635 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
3636     int32_t windowId, int32_t& mainWindowId)
3637 {
3638     auto iter = sceneSessionMap.find(windowId);
3639     if (iter == sceneSessionMap.end()) {
3640         TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
3641         return WMError::WM_ERROR_NULLPTR;
3642     }
3643     sptr<SceneSession> sceneSession = iter->second;
3644     if (sceneSession == nullptr) {
3645         TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
3646         return WMError::WM_ERROR_NULLPTR;
3647     }
3648     if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3649         mainWindowId = sceneSession->GetPersistentId();
3650         return WMError::WM_OK;
3651     }
3652     if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3653         WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
3654         return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
3655     }
3656     // not sub window, dialog, return invalid id
3657     mainWindowId = INVALID_SESSION_ID;
3658     return WMError::WM_OK;
3659 }
3660 
GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)3661 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
3662 {
3663     if (windowId == INVALID_SESSION_ID) {
3664         TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3665         return WMError::WM_ERROR_INVALID_PARAM;
3666     }
3667     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3668     return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
3669 }
3670 
HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)3671 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
3672     const sptr<SceneSession>& sceneSession)
3673 {
3674     auto systemBarProperties = property->GetSystemBarProperty();
3675     for (auto iter : systemBarProperties) {
3676         if (iter.first == type) {
3677             sceneSession->SetSystemBarProperty(iter.first, iter.second);
3678             TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
3679                 static_cast<int32_t>(iter.first), iter.second.enable_);
3680         }
3681     }
3682     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3683 }
3684 
3685 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)3686 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
3687     const sptr<SceneSession>& sceneSession)
3688 {
3689     if (!SessionPermission::IsSystemCalling()) {
3690         TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
3691         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3692     }
3693 
3694     sceneSession->SetTopmost(property->IsTopmost());
3695     return WMError::WM_OK;
3696 }
3697 
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)3698 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3699     const sptr<SceneSession>& sceneSession)
3700 {
3701     auto propertyOld = sceneSession->GetSessionProperty();
3702     if (propertyOld == nullptr) {
3703         TLOGI(WmsLogTag::DEFAULT, "session property null");
3704         return;
3705     }
3706 
3707     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
3708     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
3709     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
3710         TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
3711         return;
3712     }
3713 
3714     if (IsSessionVisibleForeground(sceneSession)) {
3715         if (hideNonSystemFloatingWindowsOld) {
3716             UpdateForceHideState(sceneSession, propertyOld, false);
3717         } else {
3718             UpdateForceHideState(sceneSession, property, true);
3719         }
3720     }
3721 }
3722 
UpdateForceHideState(const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property, bool add)3723 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
3724     const sptr<WindowSessionProperty>& property, bool add)
3725 {
3726     if (property == nullptr) {
3727         WLOGFD("property is null");
3728         return;
3729     }
3730     auto persistentId = sceneSession->GetPersistentId();
3731     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
3732     bool notifyAll = false;
3733     if (add) {
3734         if (property->GetHideNonSystemFloatingWindows()) {
3735             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
3736             notifyAll = !forceHideFloatOld;
3737         } else if (property->IsFloatingWindowAppType() && !property->GetSystemCalling()) {
3738             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
3739             if (forceHideFloatOld) {
3740                 sceneSession->NotifyForceHideChange(true);
3741             }
3742         }
3743     } else {
3744         if (property->GetHideNonSystemFloatingWindows()) {
3745             systemTopSceneSessionMap_.erase(persistentId);
3746             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
3747         } else if (property->IsFloatingWindowAppType() && !property->GetSystemCalling()) {
3748             nonSystemFloatSceneSessionMap_.erase(persistentId);
3749             if (property->GetForceHide()) {
3750                 sceneSession->NotifyForceHideChange(false);
3751             }
3752         }
3753     }
3754     if (notifyAll) {
3755         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
3756         for (const auto &item : nonSystemFloatSceneSessionMap_) {
3757             auto forceHideSceneSession = item.second;
3758             auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
3759             if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
3760                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
3761             }
3762         }
3763     }
3764 }
3765 
HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)3766 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
3767 {
3768 #ifdef POWER_MANAGER_ENABLE
3769     auto task = [this, sceneSession]() {
3770         if (sceneSession == nullptr) {
3771             WLOGFE("session is invalid");
3772             return;
3773         }
3774         WLOGFD("Win: %{public}s, is turn on%{public}d",
3775             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
3776         std::string identity = IPCSkeleton::ResetCallingIdentity();
3777         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
3778             WLOGI("turn screen on");
3779             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
3780         }
3781         // set ipc identity to raw
3782         IPCSkeleton::SetCallingIdentity(identity);
3783     };
3784     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
3785 
3786 #else
3787     WLOGFD("Can not found the sub system of PowerMgr");
3788 #endif
3789 }
3790 
HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)3791 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
3792 {
3793 #ifdef POWER_MANAGER_ENABLE
3794     wptr<SceneSession> weakSceneSession(sceneSession);
3795     auto task = [this, weakSceneSession, requireLock]() {
3796         auto scnSession = weakSceneSession.promote();
3797         if (scnSession == nullptr) {
3798             WLOGFE("session is invalid");
3799             return;
3800         }
3801         if (requireLock && scnSession->keepScreenLock_ == nullptr) {
3802             // reset ipc identity
3803             std::string identity = IPCSkeleton::ResetCallingIdentity();
3804             scnSession->keepScreenLock_ =
3805                 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
3806                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
3807             // set ipc identity to raw
3808             IPCSkeleton::SetCallingIdentity(identity);
3809         }
3810         if (scnSession->keepScreenLock_ == nullptr) {
3811             return;
3812         }
3813         bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession);
3814         TLOGNI(WmsLogTag::DEFAULT, "keep screen on: [%{public}s, %{public}d, %{public}d], %{public}d], %{public}d]",
3815             scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
3816             scnSession->IsVisible(), requireLock, shouldLock);
3817         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
3818         ErrCode res;
3819         std::string identity = IPCSkeleton::ResetCallingIdentity();
3820         if (shouldLock) {
3821             res = scnSession->keepScreenLock_->Lock();
3822         } else {
3823             res = scnSession->keepScreenLock_->UnLock();
3824         }
3825         // set ipc identity to raw
3826         IPCSkeleton::SetCallingIdentity(identity);
3827         if (res != ERR_OK) {
3828             WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
3829                 requireLock, res);
3830         }
3831     };
3832     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
3833 #else
3834     WLOGFD("Can not found the sub system of PowerMgr");
3835 #endif
3836 }
3837 
NotifyVisibleChange(int32_t persistentId)3838 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
3839 {
3840     auto sceneSession = GetSceneSession(persistentId);
3841     if (sceneSession == nullptr) {
3842         return false;
3843     }
3844     HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
3845     ProcessWindowModeType();
3846     return true;
3847 }
3848 
SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)3849 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
3850 {
3851 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
3852     if (GetDisplayBrightness() != brightness &&
3853         GetFocusedSessionId() == sceneSession->GetPersistentId()) {
3854         bool setBrightnessRet = false;
3855         if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3856             auto task = []() {
3857                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3858             };
3859             setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
3860             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3861         } else {
3862             auto task = [brightness]() {
3863                 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3864                     static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3865             };
3866             setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
3867             SetDisplayBrightness(brightness);
3868         }
3869         if (!setBrightnessRet) {
3870             WLOGFE("Report post listener callback task failed. the task name is SetBrightness");
3871         }
3872     }
3873 #else
3874     WLOGFD("Can not found the sub system of DisplayPowerMgr");
3875 #endif
3876     brightnessSessionId_ = sceneSession->GetPersistentId();
3877     return WSError::WS_OK;
3878 }
3879 
UpdateBrightness(int32_t persistentId)3880 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
3881 {
3882     auto sceneSession = GetSceneSession(persistentId);
3883     if (sceneSession == nullptr) {
3884         WLOGFE("session is invalid");
3885         return WSError::WS_ERROR_NULLPTR;
3886     }
3887     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
3888             sceneSession->GetSessionInfo().isSystem_)) {
3889         WLOGW("only app main window can set brightness");
3890         return WSError::WS_DO_NOTHING;
3891     }
3892     auto brightness = sceneSession->GetBrightness();
3893     WLOGFI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
3894     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3895         if (GetDisplayBrightness() != brightness) {
3896             WLOGI("adjust brightness with default value");
3897             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3898             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3899         }
3900         brightnessSessionId_ = INVALID_WINDOW_ID;
3901     } else {
3902         if (GetDisplayBrightness() != brightness) {
3903             WLOGI("adjust brightness with value");
3904             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3905                 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3906             SetDisplayBrightness(brightness);
3907         }
3908         brightnessSessionId_ = sceneSession->GetPersistentId();
3909     }
3910     return WSError::WS_OK;
3911 }
3912 
GetCurrentUserId() const3913 int32_t SceneSessionManager::GetCurrentUserId() const
3914 {
3915     return currentUserId_;
3916 }
3917 
SetDisplayBrightness(float brightness)3918 void SceneSessionManager::SetDisplayBrightness(float brightness)
3919 {
3920     displayBrightness_ = brightness;
3921 }
3922 
GetDisplayBrightness() const3923 float SceneSessionManager::GetDisplayBrightness() const
3924 {
3925     return displayBrightness_;
3926 }
3927 
SetGestureNavigationEnabled(bool enable)3928 WMError SceneSessionManager::SetGestureNavigationEnabled(bool enable)
3929 {
3930     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3931         TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
3932         return WMError::WM_ERROR_NOT_SYSTEM_APP;
3933     }
3934     std::string callerBundleName = SessionPermission::GetCallingBundleName();
3935     TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
3936     auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
3937         SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
3938         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
3939             WLOGFE("callback func is null");
3940             return WMError::WM_OK;
3941         }
3942         if (gestureNavigationEnabledChangeFunc_) {
3943             gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
3944         }
3945         if (statusBarEnabledChangeFunc_) {
3946             statusBarEnabledChangeFunc_(enable, bundleName);
3947         }
3948         return WMError::WM_OK;
3949     };
3950     return taskScheduler_->PostSyncTask(task, "SetGestureNavigationEnabled");
3951 }
3952 
SetFocusedSessionId(int32_t persistentId)3953 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
3954 {
3955     if (focusedSessionId_ == persistentId) {
3956         WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
3957         return WSError::WS_DO_NOTHING;
3958     }
3959     lastFocusedSessionId_ = focusedSessionId_;
3960     focusedSessionId_ = persistentId;
3961     return WSError::WS_OK;
3962 }
3963 
GetFocusedSessionId() const3964 int32_t SceneSessionManager::GetFocusedSessionId() const
3965 {
3966     return focusedSessionId_;
3967 }
3968 
GetFocusWindowInfo(FocusChangeInfo& focusInfo)3969 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
3970 {
3971     if (!SessionPermission::IsSACalling()) {
3972         WLOGFE("GetFocusWindowInfo permission denied!");
3973         return;
3974     }
3975     auto sceneSession = GetSceneSession(focusedSessionId_);
3976     if (sceneSession) {
3977         WLOGFD("Get focus session info success");
3978         focusInfo.windowId_ = sceneSession->GetWindowId();
3979         focusInfo.displayId_ = static_cast<DisplayId>(0);
3980         focusInfo.pid_ = sceneSession->GetCallingPid();
3981         focusInfo.uid_ = sceneSession->GetCallingUid();
3982         focusInfo.windowType_ = sceneSession->GetWindowType();
3983         focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
3984     }
3985     return;
3986 }
3987 
IsValidDigitString(const std::string& windowIdStr)3988 static bool IsValidDigitString(const std::string& windowIdStr)
3989 {
3990     if (windowIdStr.empty()) {
3991         return false;
3992     }
3993     for (char ch : windowIdStr) {
3994         if ((ch >= '0' && ch <= '9')) {
3995             continue;
3996         }
3997         WLOGFE("invalid window id");
3998         return false;
3999     }
4000     return true;
4001 }
4002 
RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)4003 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
4004 {
4005     if (sceneSession == nullptr) {
4006         WLOGFE("session is nullptr");
4007         return;
4008     }
4009     NotifySessionExceptionFunc sessionExceptionFunc = [this](const SessionInfo& info, bool needRemoveSession = false) {
4010         auto task = [this, info] {
4011             auto session = GetSceneSession(info.persistentId_);
4012             if (session == nullptr) {
4013                 WLOGW("NotifySessionExceptionFunc, Not found session, id: %{public}d",
4014                     info.persistentId_);
4015                 return;
4016             }
4017             if (session->GetSessionInfo().isSystem_) {
4018                 WLOGW("NotifySessionExceptionFunc, id: %{public}d is system",
4019                     session->GetPersistentId());
4020                 return;
4021             }
4022             WLOGI("NotifySessionExceptionFunc, errorCode: %{public}d, id: %{public}d",
4023                 info.errorCode, info.persistentId_);
4024             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
4025                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
4026                 WLOGD("NotifySessionClosed when ability load timeout "
4027                     "or foreground timeout, id: %{public}d", info.persistentId_);
4028                 listenerController_->NotifySessionClosed(info.persistentId_);
4029             }
4030         };
4031         taskScheduler_->PostVoidSyncTask(task, "sessionException");
4032     };
4033     sceneSession->SetSessionExceptionListener(sessionExceptionFunc, false);
4034     TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
4035 }
4036 
RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)4037 void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)
4038 {
4039     if (sceneSession == nullptr) {
4040         TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
4041         return;
4042     }
4043     VisibilityChangedDetectFunc func = [this](const int32_t pid, const bool isVisible,
4044         const bool newIsVisible) {
4045         if (isVisible == newIsVisible || pid == -1) {
4046             return;
4047         }
4048         sptr<WindowPidVisibilityInfo> windowPidVisibilityInfo = sptr<WindowPidVisibilityInfo>::MakeSptr();
4049         windowPidVisibilityInfo->pid_ = pid;
4050         int32_t count = 0;
4051         int32_t beforeCount = 0;
4052         {
4053             std::unique_lock<std::mutex> lock(visibleWindowCountMapMutex_);
4054             if (visibleWindowCountMap_.find(pid) != visibleWindowCountMap_.end()) {
4055                 beforeCount = visibleWindowCountMap_[pid];
4056             }
4057             count = newIsVisible ? beforeCount + 1 : beforeCount - 1;
4058         }
4059         if (beforeCount == 0 && count == 1) {
4060             TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid);
4061             windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE;
4062             visibleWindowCountMap_[pid] = count;
4063             SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
4064         } else if (beforeCount == 1 && count == 0) {
4065             TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid);
4066             windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE;
4067             visibleWindowCountMap_.erase(pid);
4068             SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
4069         } else if (beforeCount < 0 || count < 0) {
4070             TLOGE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid);
4071             RecoveryVisibilityPidCount(pid);
4072         } else {
4073             visibleWindowCountMap_[pid] = count;
4074         }
4075     };
4076     sceneSession->SetVisibilityChangedDetectFunc(func);
4077 }
4078 
RecoveryVisibilityPidCount(int32_t pid)4079 void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid)
4080 {
4081     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4082     int32_t count = 0;
4083     for (const auto& iter : sceneSessionMap_) {
4084         auto& session = iter.second;
4085         if (session && session->GetCallingPid() == pid && session->IsVisible()) {
4086             count++;
4087         }
4088     }
4089 
4090     if (count > 0) {
4091         visibleWindowCountMap_[pid] = count;
4092     }
4093 }
4094 
RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)4095 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
4096 {
4097     if (sceneSession == nullptr) {
4098         WLOGFE("session is nullptr");
4099         return;
4100     }
4101     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
4102         auto sceneSession = GetSceneSession(persistentId);
4103         if (sceneSession == nullptr) {
4104             WLOGW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
4105             return;
4106         }
4107         if (sceneSession->GetSessionInfo().isSystem_) {
4108             WLOGW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
4109             return;
4110         }
4111         auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
4112         if (abilityInfoPtr == nullptr) {
4113             WLOGW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
4114             return;
4115         }
4116         if (!abilityInfoPtr->excludeFromMissions) {
4117             listenerController_->NotifySessionSnapshotChanged(persistentId);
4118         }
4119     };
4120     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
4121     WLOGFD("success, id: %{public}d", sceneSession->GetPersistentId());
4122 }
4123 
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)4124 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
4125 {
4126     if (sceneSession == nullptr) {
4127         TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
4128         return;
4129     }
4130     AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
4131         config.duration_ = rotateAnimationConfig_.duration_;
4132     };
4133     sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
4134     TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d",
4135         sceneSession->GetPersistentId());
4136 }
4137 
NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)4138 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
4139 {
4140     if (sceneSession == nullptr) {
4141         WLOGFW("session is null");
4142         return;
4143     }
4144     if (sceneSession->GetSessionInfo().isSystem_) {
4145         WLOGFW("id: %{public}d is system", sceneSession->GetPersistentId());
4146         return;
4147     }
4148     if (sceneSession->GetSessionInfo().appIndex_ != 0) {
4149         WLOGFI("NotifyDestroy, appIndex: %{public}d, id: %{public}d",
4150                sceneSession->GetSessionInfo().appIndex_, sceneSession->GetPersistentId());
4151         listenerController_->NotifySessionDestroyed(sceneSession->GetPersistentId());
4152         return;
4153     }
4154     if (needRemoveSession) {
4155         WLOGFI("NotifyDestroy, needRemoveSession, id: %{public}d", sceneSession->GetPersistentId());
4156         listenerController_->NotifySessionDestroyed(sceneSession->GetPersistentId());
4157         return;
4158     }
4159     if (sceneSession->GetSessionInfo().abilityInfo == nullptr) {
4160         WLOGFW("abilityInfo is null, id: %{public}d", sceneSession->GetPersistentId());
4161     } else if ((sceneSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4162                (sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4163         WLOGFI("NotifyDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4164             sceneSession->GetPersistentId());
4165         listenerController_->NotifySessionDestroyed(sceneSession->GetPersistentId());
4166         return;
4167     }
4168     WLOGFI("NotifyClosed, id: %{public}d", sceneSession->GetPersistentId());
4169     listenerController_->NotifySessionClosed(sceneSession->GetPersistentId());
4170 }
4171 
NotifyWindowInfoChangeFromSession(int32_t persistentId)4172 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4173 {
4174     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4175     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4176     if (sceneSession == nullptr) {
4177         WLOGFE("sceneSession nullptr");
4178         return;
4179     }
4180 
4181     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4182 }
4183 
IsSessionVisible(const sptr<SceneSession>& session)4184 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4185 {
4186     if (session == nullptr) {
4187         return false;
4188     }
4189     if (Session::IsScbCoreEnabled()) {
4190         return session->IsVisible();
4191     }
4192     const auto& state = session->GetSessionState();
4193     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4194         const auto& parentSceneSession = session->GetParentSession();
4195         if (parentSceneSession == nullptr) {
4196             WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
4197             return false;
4198         }
4199         const auto& parentState = parentSceneSession->GetSessionState();
4200         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4201             if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
4202                 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
4203                 return false;
4204             }
4205             WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4206             return true;
4207         }
4208         WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4209         return false;
4210     }
4211 
4212     if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4213         WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
4214         return true;
4215     }
4216     WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
4217     return false;
4218 }
4219 
IsSessionVisibleForeground(const sptr<SceneSession>& session)4220 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4221 {
4222     if (session == nullptr) {
4223         return false;
4224     }
4225     if (Session::IsScbCoreEnabled()) {
4226         return session->IsVisibleForeground();
4227     }
4228     return IsSessionVisible(session);
4229 }
4230 
DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)4231 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4232 {
4233     if (session == nullptr) {
4234         return;
4235     }
4236     int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4237     WSRect rect = session->GetSessionRect();
4238     std::string sName;
4239     if (session->GetSessionInfo().isSystem_) {
4240         sName = session->GetSessionInfo().abilityName_;
4241     } else {
4242         sName = session->GetWindowName();
4243     }
4244     uint32_t flag = 0;
4245     uint64_t displayId = INVALID_SCREEN_ID;
4246     auto sessionProperty = session->GetSessionProperty();
4247     if (sessionProperty) {
4248         flag = sessionProperty->GetWindowFlags();
4249         displayId = sessionProperty->GetDisplayId();
4250     }
4251     uint32_t orientation = 0;
4252     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4253         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4254     // std::setw is used to set the output width and different width values are set to keep the format aligned.
4255     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4256         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4257         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4258         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4259         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4260         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4261         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4262         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4263         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4264         << "[ "
4265         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4266         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4267         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4268         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4269         << "]"
4270         << " [ "
4271         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4272         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4273         << "]"
4274         << " [ "
4275         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4276         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4277         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4278         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4279         << "]"
4280         << std::endl;
4281 }
4282 
GetAllSessionDumpInfo(std::string& dumpInfo)4283 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4284 {
4285     int32_t screenGroupId = 0;
4286     std::ostringstream oss;
4287     oss << "-------------------------------------ScreenGroup " << screenGroupId
4288         << "-------------------------------------" << std::endl;
4289     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
4290         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]"
4291         << std::endl;
4292 
4293     std::vector<sptr<SceneSession>> allSession;
4294     std::vector<sptr<SceneSession>> backgroundSession;
4295     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4296     {
4297         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4298         sceneSessionMapCopy = sceneSessionMap_;
4299     }
4300     for (const auto& elem : sceneSessionMapCopy) {
4301         auto curSession = elem.second;
4302         if (curSession == nullptr) {
4303             continue;
4304         }
4305         if (IsSessionVisibleForeground(curSession)) {
4306             allSession.push_back(curSession);
4307         } else {
4308             backgroundSession.push_back(curSession);
4309         }
4310     }
4311     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4312     uint32_t count = 0;
4313     for (const auto& session : allSession) {
4314         if (session == nullptr) {
4315             continue;
4316         }
4317         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4318             oss << "---------------------------------------------------------------------------------------"
4319                 << std::endl;
4320         }
4321         DumpSessionInfo(session, oss);
4322         count++;
4323     }
4324     oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4325     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4326     dumpInfo.append(oss.str());
4327     return WSError::WS_OK;
4328 }
4329 
GetAllSessionDumpDetailInfo(std::string& dumpInfo)4330 WSError SceneSessionManager::GetAllSessionDumpDetailInfo(std::string& dumpInfo)
4331 {
4332     std::ostringstream oss;
4333     std::vector<sptr<SceneSession>> allSession;
4334     std::vector<sptr<SceneSession>> backgroundSession;
4335 
4336     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4337     {
4338         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4339         sceneSessionMapCopy = sceneSessionMap_;
4340     }
4341     for (const auto& elem : sceneSessionMapCopy) {
4342         auto curSession = elem.second;
4343         if (curSession == nullptr) {
4344             continue;
4345         }
4346         if (IsSessionVisibleForeground(curSession)) {
4347             allSession.push_back(curSession);
4348         } else {
4349             backgroundSession.push_back(curSession);
4350         }
4351     }
4352     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4353     HidumpController::GetInstance().GetAllSessionDumpDetailedInfo(oss, allSession, backgroundSession);
4354     dumpInfo.append(oss.str());
4355     return WSError::WS_OK;
4356 }
4357 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)4358 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4359 {
4360     dumpRootSceneFunc_ = func;
4361 }
4362 
DumpSessionElementInfo(const sptr<SceneSession>& session, const std::vector<std::string>& params, std::string& dumpInfo)4363 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4364     const std::vector<std::string>& params, std::string& dumpInfo)
4365 {
4366     std::vector<std::string> resetParams;
4367     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4368     if (resetParams.empty()) {
4369         WLOGI("do not dump ui info");
4370         return;
4371     }
4372 
4373     if (!session->GetSessionInfo().isSystem_) {
4374         WLOGFI("Dump normal session, not system");
4375         dumpInfoFuture_.ResetLock({});
4376         session->DumpSessionElementInfo(resetParams);
4377         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4378         for (auto& info: infos) {
4379             dumpInfo.append(info).append("\n");
4380         }
4381     } else {
4382         WLOGFI("Dump system session");
4383         std::vector<std::string> infos;
4384         dumpRootSceneFunc_(resetParams, infos);
4385         for (auto& info: infos) {
4386             dumpInfo.append(info).append("\n");
4387         }
4388     }
4389 }
4390 
GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params, const std::string& strId)4391 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4392     const std::string& strId)
4393 {
4394     uint64_t persistentId = std::stoull(strId);
4395     auto session = GetSceneSession(persistentId);
4396     if (session == nullptr) {
4397         return WSError::WS_ERROR_INVALID_PARAM;
4398     }
4399     auto sessionProperty = session->GetSessionProperty();
4400     if (sessionProperty == nullptr) {
4401         return WSError::WS_ERROR_INVALID_PARAM;
4402     }
4403 
4404     WSRect rect = session->GetSessionRect();
4405     std::string isVisible = session->IsVisible() ? "true" : "false";
4406     std::string focusable = session->GetFocusable() ? "true" : "false";
4407     std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4408     bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4409     std::string isPrivacyMode = privacyMode ? "true" : "false";
4410     bool isFirstFrameAvailable = true;
4411     std::ostringstream oss;
4412     oss << "WindowName: " << session->GetWindowName()  << std::endl;
4413     oss << "DisplayId: " << 0 << std::endl;
4414     oss << "WinId: " << session->GetPersistentId() << std::endl;
4415     oss << "Pid: " << session->GetCallingPid() << std::endl;
4416     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4417     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4418     oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4419     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4420     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4421     oss << "IsVisible: " << isVisible << std::endl;
4422     oss << "isRSVisible: " << (session->GetRSVisible() ? "true" : "false") << std::endl;
4423     oss << "Focusable: "  << focusable << std::endl;
4424     oss << "DecoStatus: "  << decoStatus << std::endl;
4425     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
4426     oss << "WindowRect: " << "[ "
4427         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4428         << " ]" << std::endl;
4429     oss << "scaleX: " << session->GetScaleX() << std::endl;
4430     oss << "scaleY: " << session->GetScaleY() << std::endl;
4431     oss << "Offset: " << "[ "
4432         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4433     oss << "Scale: " << "[ "
4434         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4435         << session->GetPivotX() << ", " << session->GetPivotY()
4436         << " ]" << std::endl;
4437     dumpInfo.append(oss.str());
4438 
4439     DumpSessionElementInfo(session, params, dumpInfo);
4440     return WSError::WS_OK;
4441 }
4442 
GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)4443 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)
4444 {
4445     // publish data
4446     bool ret = eventHandler_->PostSyncTask(
4447         [this, cmd = std::move(cmd)] { return scbDumpSubscriber_->Publish(cmd); }, "PublishSCBDumper");
4448     if (!ret) {
4449         return WSError::WS_ERROR_INVALID_OPERATION;
4450     }
4451     // get response event
4452     auto task = [this, &dumpInfo] {
4453         dumpInfo.append(scbDumpSubscriber_->GetDebugDumpInfo(WAIT_TIME));
4454         return WSError::WS_OK;
4455     };
4456     eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4457     return WSError::WS_OK;
4458 }
4459 
NotifyDumpInfoResult(const std::vector<std::string>& info)4460 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4461 {
4462     dumpInfoFuture_.SetValue(info);
4463     WLOGFD("NotifyDumpInfoResult");
4464 }
4465 
GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)4466 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4467 {
4468     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4469         WLOGFE("GetSessionDumpInfo permission denied!");
4470         return WSError::WS_ERROR_INVALID_PERMISSION;
4471     }
4472     auto task = [this, params, &dumpInfo]() {
4473         if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4474             return GetAllSessionDumpInfo(dumpInfo);
4475         }
4476         if (params.size() == 1 && params[0] == ARG_DUMP_DETAIL) { // 1: params num
4477             return GetAllSessionDumpDetailInfo(dumpInfo);
4478         }
4479         if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4480             return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4481         }
4482         if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2: params num
4483             std::string cmd;
4484             std::for_each(params.begin() + 1, params.end(),
4485                           [&cmd](const std::string& value) {
4486                               cmd += value;
4487                               cmd += ' ';
4488                           });
4489             return GetSCBDebugDumpInfo(std::move(cmd), dumpInfo);
4490         }
4491         if (params.size() >= 2 && params[0] == ARG_DUMP_PIPLINE && IsValidDigitString(params[1])) { // 2: params num
4492             return GetTotalUITreeInfo(params[1], dumpInfo);
4493         }
4494         return WSError::WS_ERROR_INVALID_OPERATION;
4495     };
4496     return taskScheduler_->PostSyncTask(task);
4497 }
4498 
GetTotalUITreeInfo(const std::string& strId, std::string& dumpInfo)4499 WSError SceneSessionManager::GetTotalUITreeInfo(const std::string& strId, std::string& dumpInfo)
4500 {
4501     TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4502     uint64_t screenId = std::stoull(strId);
4503     if (dumpUITreeFunc_) {
4504         dumpUITreeFunc_(screenId, dumpInfo);
4505     } else {
4506         TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4507     }
4508     return WSError::WS_OK;
4509 }
4510 
SetDumpUITreeFunc(const DumpUITreeFunc& func)4511 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4512 {
4513     dumpUITreeFunc_ = func;
4514 }
4515 
FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)4516 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4517 {
4518     // notify RS
4519     WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4520         " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4521         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4522         sceneSession->GetSessionInfo().bundleName_.c_str(),
4523         sceneSession->GetSessionInfo().abilityName_.c_str(),
4524         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4525     uint64_t focusNodeId = 0; // 0 means invalid
4526     if (sceneSession->GetSurfaceNode() == nullptr) {
4527         WLOGFW("focused window surfaceNode is null");
4528     } else {
4529         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4530     }
4531     FocusAppInfo appInfo = {
4532         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4533         sceneSession->GetSessionInfo().bundleName_,
4534         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4535     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4536 }
4537 
4538 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4539 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4540 {
4541     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4542     {
4543         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4544         for (auto& iter : sceneSessionMap_) {
4545             ret.push_back(iter);
4546         }
4547     }
4548     std::sort(ret.begin(), ret.end(), cmp);
4549     return ret;
4550 }
4551 
TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)4552 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4553 {
4554     if (isFromTopToBottom) {
4555         TraverseSessionTreeFromTopToBottom(func);
4556     } else {
4557         TraverseSessionTreeFromBottomToTop(func);
4558     }
4559     return;
4560 }
4561 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4562 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4563 {
4564     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4565         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4566         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4567         return lhsZOrder < rhsZOrder;
4568     };
4569     auto sceneSessionVector = GetSceneSessionVector(cmp);
4570 
4571     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
4572         auto session = iter->second;
4573         if (session == nullptr) {
4574             WLOGFE("session is nullptr");
4575             continue;
4576         }
4577         if (func(session)) {
4578             return;
4579         }
4580     }
4581     return;
4582 }
4583 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)4584 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
4585 {
4586     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4587     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4588         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4589         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4590         return lhsZOrder < rhsZOrder;
4591     };
4592     auto sceneSessionVector = GetSceneSessionVector(cmp);
4593     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
4594     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
4595         auto session = iter->second;
4596         if (session == nullptr) {
4597             WLOGFE("session is nullptr");
4598             continue;
4599         }
4600         if (func(session)) {
4601             return;
4602         }
4603     }
4604     return;
4605 }
4606 
RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground, FocusChangeReason reason)4607 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
4608     FocusChangeReason reason)
4609 {
4610     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4611     auto sceneSession = GetSceneSession(persistentId);
4612     if (sceneSession == nullptr) {
4613         TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
4614         return WMError::WM_ERROR_NULLPTR;
4615     }
4616     int32_t callingPid = IPCSkeleton::GetCallingPid();
4617     if (callingPid != sceneSession->GetCallingPid() &&
4618         !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
4619         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
4620         return WMError::WM_ERROR_INVALID_CALLING;
4621     }
4622     auto task = [this, persistentId, isFocused, byForeground, reason]() {
4623         if (isFocused) {
4624             RequestSessionFocus(persistentId, byForeground, reason);
4625         } else {
4626             RequestSessionUnfocus(persistentId, reason);
4627         }
4628     };
4629     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
4630     focusChangeReason_ = reason;
4631     return WMError::WM_OK;
4632 }
4633 
RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground, FocusChangeReason reason)4634 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
4635     FocusChangeReason reason)
4636 {
4637     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4638     auto task = [this, persistentId, isFocused, byForeground, reason]() {
4639         if (isFocused) {
4640             if (reason == FocusChangeReason::FOREGROUND) {
4641                 RequestSessionFocusImmediately(persistentId);
4642                 return;
4643             }
4644             if (reason == FocusChangeReason::MOVE_UP) {
4645                 auto session = GetSceneSession(persistentId);
4646                 if (session && !session->IsFocused()) {
4647                     PostProcessFocusState state = { true, true, byForeground, reason };
4648                     session->SetPostProcessFocusState(state);
4649                 }
4650                 return;
4651             }
4652             if (reason == FocusChangeReason::CLICK) {
4653                 return;
4654             }
4655             if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
4656                 auto session = GetSceneSession(persistentId);
4657                 if (session && !session->IsFocused()) {
4658                     PostProcessFocusState state = { true, true, byForeground, reason };
4659                     session->SetPostProcessFocusState(state);
4660                 }
4661             }
4662         } else {
4663             RequestSessionUnfocus(persistentId, reason);
4664         }
4665     };
4666     taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
4667     return WMError::WM_OK;
4668 }
4669 
RequestAllAppSessionUnfocus()4670 void SceneSessionManager::RequestAllAppSessionUnfocus()
4671 {
4672     auto task = [this]() {
4673         RequestAllAppSessionUnfocusInner();
4674     };
4675     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
4676     return;
4677 }
4678 
4679 /**
4680  * request focus and ignore its state
4681  * only used when app main window start before foreground
4682 */
RequestSessionFocusImmediately(int32_t persistentId)4683 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
4684 {
4685     TLOGI(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
4686     // base block
4687     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4688     if (basicCheckRet != WSError::WS_OK) {
4689         return basicCheckRet;
4690     }
4691     auto sceneSession = GetSceneSession(persistentId);
4692     if (sceneSession == nullptr) {
4693         WLOGFE("[WMSComm]session is nullptr");
4694         return WSError::WS_ERROR_INVALID_SESSION;
4695     }
4696     if (!sceneSession->CheckFocusable()) {
4697         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
4698         return WSError::WS_DO_NOTHING;
4699     }
4700     if (!sceneSession->IsFocusedOnShow()) {
4701         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4702         return WSError::WS_DO_NOTHING;
4703     }
4704 
4705     // specific block
4706     FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
4707     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
4708     if (specificCheckRet != WSError::WS_OK) {
4709         return specificCheckRet;
4710     }
4711 
4712     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4713     if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
4714         needBlockNotifyFocusStatusUntilForeground_ = true;
4715     }
4716     ShiftFocus(sceneSession, reason);
4717     return WSError::WS_OK;
4718 }
4719 
RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)4720 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
4721 {
4722     TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
4723         persistentId, byForeground, reason);
4724     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4725     if (basicCheckRet != WSError::WS_OK) {
4726         return basicCheckRet;
4727     }
4728     auto sceneSession = GetSceneSession(persistentId);
4729     if (sceneSession == nullptr) {
4730         WLOGFE("[WMSComm]session is nullptr");
4731         return WSError::WS_ERROR_INVALID_SESSION;
4732     }
4733     if (!sceneSession->CheckFocusable() || !IsSessionVisibleForeground(sceneSession)) {
4734         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
4735         return WSError::WS_DO_NOTHING;
4736     }
4737     if (!sceneSession->IsFocusedOnShow()) {
4738         TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4739         return WSError::WS_DO_NOTHING;
4740     }
4741 
4742     // subwindow/dialog state block
4743     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4744         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4745         GetSceneSession(sceneSession->GetParentPersistentId()) &&
4746         !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
4747             TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
4748                 sceneSession->GetParentPersistentId());
4749             return WSError::WS_DO_NOTHING;
4750     }
4751     // specific block
4752     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
4753     if (specificCheckRet != WSError::WS_OK) {
4754         return specificCheckRet;
4755     }
4756 
4757     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4758     needBlockNotifyFocusStatusUntilForeground_ = false;
4759     ShiftFocus(sceneSession, reason);
4760     return WSError::WS_OK;
4761 }
4762 
RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)4763 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
4764 {
4765     TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
4766     if (persistentId == INVALID_SESSION_ID) {
4767         WLOGFE("id is invalid");
4768         return WSError::WS_ERROR_INVALID_SESSION;
4769     }
4770     auto focusedSession = GetSceneSession(focusedSessionId_);
4771     if (persistentId != focusedSessionId_ &&
4772         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
4773         TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
4774         return WSError::WS_DO_NOTHING;
4775     }
4776     // if pop menu created by desktop request unfocus, back to desktop
4777     auto lastSession = GetSceneSession(lastFocusedSessionId_);
4778     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
4779         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
4780         RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
4781             TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
4782             return WSError::WS_OK;
4783     }
4784     auto nextSession = GetNextFocusableSession(persistentId);
4785     if (nextSession == nullptr) {
4786         DumpAllSessionFocusableInfo(persistentId);
4787     }
4788 
4789     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4790     needBlockNotifyFocusStatusUntilForeground_ = false;
4791 
4792     if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
4793         return WSError::WS_OK;
4794     }
4795 
4796     return ShiftFocus(nextSession, reason);
4797 }
4798 
RequestAllAppSessionUnfocusInner()4799 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
4800 {
4801     TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
4802     auto focusedSession = GetSceneSession(focusedSessionId_);
4803     if (!focusedSession) {
4804         TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
4805         return WSError::WS_DO_NOTHING;
4806     }
4807     if (!focusedSession->IsAppSession()) {
4808         WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
4809         return WSError::WS_DO_NOTHING;
4810     }
4811     auto nextSession = GetTopFocusableNonAppSession();
4812 
4813     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4814     needBlockNotifyFocusStatusUntilForeground_ = false;
4815     return ShiftFocus(nextSession, FocusChangeReason::WIND);
4816 }
4817 
RequestFocusBasicCheck(int32_t persistentId)4818 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
4819 {
4820     // basic focus rule
4821     if (persistentId == INVALID_SESSION_ID) {
4822         TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
4823         return WSError::WS_ERROR_INVALID_SESSION;
4824     }
4825     if (persistentId == focusedSessionId_) {
4826         TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
4827         return WSError::WS_DO_NOTHING;
4828     }
4829     return WSError::WS_OK;
4830 }
4831 
4832 /**
4833  * @note @window.focus
4834  * When high zOrder System Session unfocus, check if the last focused app window can focus.
4835  */
CheckLastFocusedAppSessionFocus( sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)4836 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
4837     sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
4838 {
4839     if (focusedSession == nullptr || nextSession == nullptr) {
4840         return false;
4841     }
4842 
4843     TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
4844         lastFocusedAppSessionId_, nextSession->GetPersistentId());
4845 
4846     if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
4847         return false;
4848     }
4849 
4850     if (!focusedSession->IsSystemSessionAboveApp()) {
4851         return false;
4852     }
4853 
4854     auto mode = nextSession->GetWindowMode();
4855     // only when next session is app, and in split or floation
4856     if (nextSession->IsAppSession() &&
4857         (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
4858          mode == WindowMode::WINDOW_MODE_FLOATING)) {
4859         if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
4860             WSError::WS_OK) {
4861             return true;
4862         }
4863         lastFocusedAppSessionId_ = INVALID_SESSION_ID;
4864     }
4865     return false;
4866 }
4867 
4868 /**
4869  * When switching focus, check if the blockingType window has been  traversed downwards.
4870  *
4871  * @return true: traversed downwards, false: not.
4872  */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession, sptr<SceneSession>& focusedSession, bool includingAppSession)4873 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
4874     sptr<SceneSession>& focusedSession, bool includingAppSession)
4875 {
4876     uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
4877     uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
4878     TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
4879         requestSessionZOrder, focusedSessionZOrder);
4880     if  (requestSessionZOrder < focusedSessionZOrder)  {
4881         auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
4882             includingAppSession);
4883         uint32_t topNearestBlockingZOrder = 0;
4884         if  (topNearestBlockingFocusSession)  {
4885             topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
4886             TLOGD(WmsLogTag::WMS_FOCUS,  "requestSessionZOrder: %{public}d, focusedSessionZOrder:  %{public}d\
4887                 topNearestBlockingZOrder:  %{public}d",  requestSessionZOrder,  focusedSessionZOrder,
4888                 topNearestBlockingZOrder);
4889         }
4890         if  (focusedSessionZOrder >=  topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder)  {
4891             TLOGD(WmsLogTag::WMS_FOCUS,  "focus pass through, needs to be intercepted");
4892             return true;
4893         }
4894     }
4895     TLOGD(WmsLogTag::WMS_FOCUS, "not through");
4896     return false;
4897 }
4898 
CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)4899 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
4900 {
4901     bool isFocusedMainSessionTopmost =
4902         focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
4903     auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
4904     bool isFocusedSessionParentTopmost = parentSession &&
4905         parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
4906     if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
4907         (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
4908         return true;
4909     }
4910     return false;
4911 }
4912 
CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)4913 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
4914 {
4915     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4916          (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
4917         (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
4918          ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
4919         TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
4920         return true;
4921     }
4922     return false;
4923 }
4924 
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession, const sptr<SceneSession>& sceneSession, FocusChangeReason reason)4925 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
4926     const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
4927 {
4928     if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
4929         focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
4930         return false;
4931     }
4932     if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
4933         return false;
4934     }
4935     return sceneSession->GetZOrder() < focusedSession->GetZOrder();
4936 }
4937 
RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground, FocusChangeReason reason)4938 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
4939     FocusChangeReason reason)
4940 {
4941     TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
4942     int32_t persistentId = sceneSession->GetPersistentId();
4943     if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
4944         TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
4945         return WSError::WS_ERROR_INVALID_OPERATION;
4946     }
4947     // dialog get focus
4948     if (CheckRequestFocusImmdediately(sceneSession)) {
4949         return WSError::WS_DO_NOTHING;
4950     }
4951     // blocking-type session will block lower zOrder request focus
4952     auto focusedSession = GetSceneSession(focusedSessionId_);
4953     if (focusedSession) {
4954         TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d",  reason,
4955             byForeground);
4956         if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
4957             // return ok if focused session is topmost
4958             return WSError::WS_OK;
4959         }
4960         if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
4961             sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
4962             TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
4963             byForeground = false;
4964         }
4965         if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession,  focusedSession,  true))  {
4966             TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
4967             return WSError::WS_DO_NOTHING;
4968         }
4969         if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
4970             !byForeground)  {
4971             if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
4972                 && focusedSession->IsAppSession()) {
4973                 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
4974                 return WSError::WS_OK;
4975             }
4976         }
4977         bool isBlockingType = focusedSession->IsAppSession() ||
4978             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
4979         // temp check
4980         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
4981             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
4982                 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
4983                     persistentId);
4984                 return WSError::WS_DO_NOTHING;
4985         }
4986         // desktop click temp check
4987         if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
4988             TLOGD(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
4989             return WSError::WS_DO_NOTHING;
4990         }
4991     }
4992     return WSError::WS_OK;
4993 }
4994 
IsParentSessionVisible(const sptr<SceneSession>& session)4995 bool SceneSessionManager::IsParentSessionVisible(const sptr<SceneSession>& session)
4996 {
4997     if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
4998         session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
4999         auto parentSession = GetSceneSession(session->GetParentPersistentId());
5000         return parentSession == nullptr || IsSessionVisibleForeground(parentSession);
5001     }
5002     return true;
5003 }
5004 
DumpAllSessionFocusableInfo(int32_t persistentId)5005 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
5006 {
5007     TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
5008     auto func = [this](const sptr<SceneSession>& session) {
5009         if (session == nullptr) {
5010             return false;
5011         }
5012         bool parentVisible = IsParentSessionVisible(session);
5013         bool sessionVisible = IsSessionVisible(session);
5014         TLOGNI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
5015             "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
5016             session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
5017             session->GetFocusable(), sessionVisible, parentVisible);
5018         return false;
5019     };
5020     TraverseSessionTree(func, true);
5021 }
5022 
GetNextFocusableSession(int32_t persistentId)5023 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
5024 {
5025     TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
5026     bool previousFocusedSessionFound = false;
5027     sptr<SceneSession> ret = nullptr;
5028     auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
5029         if (session == nullptr) {
5030             return false;
5031         }
5032         if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5033             TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5034             return false;
5035         }
5036         if (previousFocusedSessionFound && session->CheckFocusable() &&
5037             IsSessionVisibleForeground(session) && IsParentSessionVisible(session)) {
5038             ret = session;
5039             return true;
5040         }
5041         if (session->GetPersistentId() == persistentId) {
5042             previousFocusedSessionFound = true;
5043         }
5044         return false;
5045     };
5046     TraverseSessionTree(func, true);
5047     return ret;
5048 }
5049 
5050 /**
5051  * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
5052  * and it is the closest;
5053  */
GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)5054 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
5055 {
5056     sptr<SceneSession> ret = nullptr;
5057     auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
5058         if (session == nullptr) {
5059             return false;
5060         }
5061         uint32_t sessionZOrder = session->GetZOrder();
5062         if (sessionZOrder <= zOrder) { // must be above the target session
5063             return false;
5064         }
5065         if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5066             TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
5067             return false;
5068         }
5069         auto parentSession = GetSceneSession(session->GetParentPersistentId());
5070         if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
5071             parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5072             parentSession->IsTopmost()) {
5073             TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
5074             return false;
5075         }
5076         bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
5077         bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
5078                               (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
5079                               (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
5080         if (IsSessionVisibleForeground(session) && isBlockingType)  {
5081             ret = session;
5082             return true;
5083         }
5084         return false;
5085     };
5086     TraverseSessionTree(func, false);
5087     return ret;
5088 }
5089 
GetTopFocusableNonAppSession()5090 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
5091 {
5092     TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
5093     sptr<SceneSession> ret = nullptr;
5094     auto func = [this, &ret](sptr<SceneSession> session) {
5095         if (session == nullptr) {
5096             return false;
5097         }
5098         if (session->IsAppSession()) {
5099             return true;
5100         }
5101         if (session->CheckFocusable() && IsSessionVisibleForeground(session)) {
5102             ret = session;
5103         }
5104         return false;
5105     };
5106     TraverseSessionTree(func, false);
5107     return ret;
5108 }
5109 
SetShiftFocusListener(const ProcessShiftFocusFunc& func)5110 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
5111 {
5112     TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
5113     shiftFocusFunc_ = func;
5114 }
5115 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)5116 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5117 {
5118     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
5119     notifySCBAfterFocusedFunc_ = func;
5120 }
5121 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)5122 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5123 {
5124     TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
5125     notifySCBAfterUnfocusedFunc_ = func;
5126 }
5127 
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)5128 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
5129 {
5130     WLOGFD("SetCallingSessionIdSessionListenser");
5131     callingSessionIdChangeFunc_ = func;
5132 }
5133 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)5134 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
5135 {
5136     WLOGFD("SetStartUIAbilityErrorListener");
5137     startUIAbilityErrorFunc_ = func;
5138 }
5139 
SetAbilityManagerCollaboratorRegisteredFunc( const AbilityManagerCollaboratorRegisteredFunc& func)5140 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
5141     const AbilityManagerCollaboratorRegisteredFunc& func)
5142 {
5143     auto task = [this, func] {
5144         abilityManagerCollaboratorRegisteredFunc_ = func;
5145     };
5146     taskScheduler_->PostAsyncTask(task, __func__);
5147 }
5148 
ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)5149 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)
5150 {
5151     // unfocus
5152     int32_t focusedId = focusedSessionId_;
5153     auto focusedSession = GetSceneSession(focusedSessionId_);
5154     UpdateFocusStatus(focusedSession, false);
5155     // focus
5156     int32_t nextId = INVALID_SESSION_ID;
5157     if (nextSession == nullptr) {
5158         std::string sessionLog(GetAllSessionFocusInfo());
5159         TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
5160             focusedSessionId_, sessionLog.c_str());
5161     } else {
5162         nextId = nextSession->GetPersistentId();
5163     }
5164     UpdateFocusStatus(nextSession, true);
5165     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5166     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5167     AnomalyDetection::FocusCheckProcess(focusedId, nextId);
5168     if (!scbPrevFocus && scbCurrFocus) {
5169         if (notifySCBAfterFocusedFunc_ != nullptr) {
5170             notifySCBAfterFocusedFunc_();
5171         }
5172     } else if (scbPrevFocus && !scbCurrFocus) {
5173         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5174             notifySCBAfterUnfocusedFunc_();
5175         }
5176     }
5177     TLOGI(WmsLogTag::WMS_FOCUS, "focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5178         focusedId, nextId, reason);
5179     return WSError::WS_OK;
5180 }
5181 
UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)5182 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5183 {
5184     if (sceneSession == nullptr) {
5185         if (isFocused) {
5186             SetFocusedSessionId(INVALID_SESSION_ID);
5187             lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5188         }
5189         return;
5190     }
5191     TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5192         sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5193     // set focused
5194     if (isFocused) {
5195         SetFocusedSessionId(sceneSession->GetPersistentId());
5196         if (sceneSession->IsAppOrLowerSystemSession()) {
5197             lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5198         }
5199     }
5200     sceneSession->UpdateFocus(isFocused);
5201     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5202         NotifyFocusStatus(sceneSession, isFocused);
5203     }
5204 }
5205 
NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)5206 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5207 {
5208     if (sceneSession == nullptr) {
5209         WLOGFE("[WMSComm]session is nullptr");
5210         if (isFocused) {
5211             auto prevSession = GetSceneSession(lastFocusedSessionId_);
5212             NotifyUnFocusedByMission(prevSession);
5213         }
5214         return;
5215     }
5216     int32_t persistentId = sceneSession->GetPersistentId();
5217 
5218     TLOGI(WmsLogTag::WMS_FOCUS,
5219         "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5220         sceneSession->GetSessionInfo().bundleName_.c_str(),
5221         sceneSession->GetSessionInfo().abilityName_.c_str(),
5222         sceneSession->GetWindowNameAllType().c_str(),
5223         persistentId, isFocused);
5224     if (isFocused) {
5225         if (IsSessionVisibleForeground(sceneSession)) {
5226             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5227         }
5228         UpdateBrightness(focusedSessionId_);
5229         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5230         if (shiftFocusFunc_ != nullptr) {
5231             shiftFocusFunc_(persistentId);
5232         }
5233     }
5234     // notify window manager
5235     sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
5236         sceneSession->GetWindowId(),
5237         static_cast<DisplayId>(0),
5238         sceneSession->GetCallingPid(),
5239         sceneSession->GetCallingUid(),
5240         sceneSession->GetWindowType(),
5241         sceneSession->GetAbilityToken()
5242     );
5243     SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5244     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5245     sceneSession->NotifyFocusStatus(isFocused);
5246     std::string sName = "FoucusWindow:";
5247     if (sceneSession->GetSessionInfo().isSystem_) {
5248         sName += sceneSession->GetSessionInfo().abilityName_;
5249     } else {
5250         sName += sceneSession->GetWindowName();
5251     }
5252     if (isFocused) {
5253         StartAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
5254     } else {
5255         FinishAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
5256     }
5257 
5258     // notify listenerController
5259     auto prevSession = GetSceneSession(lastFocusedSessionId_);
5260     if (isFocused && MissionChanged(prevSession, sceneSession)) {
5261         NotifyFocusStatusByMission(prevSession, sceneSession);
5262     }
5263 }
5264 
NotifyRssThawApp(const int32_t uid, const std::string& bundleName, const std::string& reason)5265 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5266     const std::string& reason)
5267 {
5268     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5269     nlohmann::json payload;
5270     payload.emplace("uid", uid);
5271     payload.emplace("bundleName", bundleName);
5272     payload.emplace("reason", reason);
5273     nlohmann::json reply;
5274     int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5275     return ret;
5276 }
5277 
NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)5278 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5279 {
5280     if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5281         TLOGD(WmsLogTag::WMS_FOCUS, "Unfocused, id: %{public}d", prevSession->GetMissionId());
5282         listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5283     }
5284     if (currSession && !currSession->GetSessionInfo().isSystem_) {
5285         TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", currSession->GetMissionId());
5286         listenerController_->NotifySessionFocused(currSession->GetMissionId());
5287     }
5288 }
5289 
NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)5290 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5291 {
5292     if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5293         TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", sceneSession->GetMissionId());
5294         listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5295     }
5296 }
5297 
MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)5298 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5299 {
5300     if (prevSession == nullptr && currSession == nullptr) {
5301         return false;
5302     }
5303     if (prevSession == nullptr || currSession == nullptr) {
5304         return true;
5305     }
5306     return prevSession->GetMissionId() != currSession->GetMissionId();
5307 }
5308 
GetAllSessionFocusInfo()5309 std::string SceneSessionManager::GetAllSessionFocusInfo()
5310 {
5311     std::ostringstream os;
5312     auto func = [&os](sptr<SceneSession> session) {
5313         if (session == nullptr) {
5314             WLOGE("sceneSession is nullptr");
5315             return false;
5316         }
5317         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5318            " ,focusable: "<< session->GetFocusable() << ";";
5319         return false;
5320     };
5321     TraverseSessionTree(func, true);
5322     return os.str();
5323 }
5324 
UpdateFocus(int32_t persistentId, bool isFocused)5325 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5326 {
5327     auto task = [this, persistentId, isFocused]() {
5328         // notify session and client
5329         auto sceneSession = GetSceneSession(persistentId);
5330         if (sceneSession == nullptr) {
5331             WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5332             return WSError::WS_ERROR_INVALID_WINDOW;
5333         }
5334         WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5335             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5336         // focusId change
5337         if (isFocused) {
5338             SetFocusedSessionId(persistentId);
5339             UpdateBrightness(focusedSessionId_);
5340             FocusIDChange(persistentId, sceneSession);
5341         } else if (persistentId == GetFocusedSessionId()) {
5342             SetFocusedSessionId(INVALID_SESSION_ID);
5343         }
5344         // notify window manager
5345         sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
5346             sceneSession->GetWindowId(),
5347             static_cast<DisplayId>(0),
5348             sceneSession->GetCallingPid(),
5349             sceneSession->GetCallingUid(),
5350             sceneSession->GetWindowType(),
5351             sceneSession->GetAbilityToken()
5352         );
5353         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5354         WSError res = WSError::WS_OK;
5355         res = sceneSession->UpdateFocus(isFocused);
5356         if (res != WSError::WS_OK) {
5357             return res;
5358         }
5359         WLOGI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5360                sceneSession->GetSessionInfo().isSystem_);
5361         if (!sceneSession->GetSessionInfo().isSystem_) {
5362             if (isFocused) {
5363                 WLOGD("NotifyFocused, id: %{public}d", sceneSession->GetPersistentId());
5364                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5365             } else {
5366                 WLOGD("NotifyUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5367                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5368             }
5369         }
5370         return WSError::WS_OK;
5371     };
5372 
5373     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5374     return WSError::WS_OK;
5375 }
5376 
UpdateWindowMode(int32_t persistentId, int32_t windowMode)5377 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5378 {
5379     WLOGFD("id: %{public}d, mode: %{public}d", persistentId, windowMode);
5380     auto sceneSession = GetSceneSession(persistentId);
5381     if (sceneSession == nullptr) {
5382         WLOGFE("could not find window, Id:%{public}d", persistentId);
5383         return WSError::WS_ERROR_INVALID_WINDOW;
5384     }
5385     WindowMode mode = static_cast<WindowMode>(windowMode);
5386     return sceneSession->UpdateWindowMode(mode);
5387 }
5388 
5389 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, MMI::PointerEvent::PointerItem& pointerItem)5390 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
5391     MMI::PointerEvent::PointerItem& pointerItem)
5392 {
5393     struct PointerEventData {
5394         double x;
5395         double y;
5396         uint64_t time;
5397     } pointerEventData = {
5398         .x = pointerItem.GetDisplayX(),
5399         .y = pointerItem.GetDisplayY(),
5400         .time = pointerEvent->GetActionTime()
5401     };
5402 
5403     const uint32_t MAX_HMAC_SIZE = 64;
5404     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
5405     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
5406     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
5407     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
5408         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
5409         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
5410     }
5411 }
5412 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
5413 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)5414 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
5415 {
5416     if (!pointerEvent) {
5417         WLOGFE("pointerEvent is null");
5418         return WSError::WS_ERROR_NULLPTR;
5419     }
5420     MMI::PointerEvent::PointerItem pointerItem;
5421     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
5422         WLOGFE("Failed to get pointerItem");
5423         return WSError::WS_ERROR_INVALID_PARAM;
5424     }
5425 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
5426     FillSecCompEnhanceData(pointerEvent, pointerItem);
5427 #endif
5428     TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d, action=%{public}d, deviceId=%{public}d, zIndex=%{public}ud",
5429         pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
5430     pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
5431     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
5432     return WSError::WS_OK;
5433 }
5434 
SetScreenLocked(const bool isScreenLocked)5435 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
5436 {
5437     isScreenLocked_ = isScreenLocked;
5438     DeleteStateDetectTask();
5439 }
5440 
DeleteStateDetectTask()5441 void SceneSessionManager::DeleteStateDetectTask()
5442 {
5443     if (!IsScreenLocked()) {
5444         return;
5445     }
5446     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5447     for (auto iter : sceneSessionMap_) {
5448         auto& session = iter.second;
5449         if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
5450             taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
5451             DetectTaskInfo detectTaskInfo;
5452             session->SetDetectTaskInfo(detectTaskInfo);
5453         }
5454     }
5455 }
5456 
IsScreenLocked() const5457 bool SceneSessionManager::IsScreenLocked() const
5458 {
5459     return isScreenLocked_;
5460 }
5461 
RegisterWindowChanged(const WindowChangedFunc& func)5462 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
5463 {
5464     WindowChangedFunc_ = func;
5465 }
5466 
JudgeNeedNotifyPrivacyInfo(DisplayId displayId, const std::unordered_set<std::string>& privacyBundles)5467 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
5468     const std::unordered_set<std::string>& privacyBundles)
5469 {
5470     bool needNotify = false;
5471     static int reSendTimes = MAX_RESEND_TIMES;
5472     std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
5473     do {
5474         if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
5475             TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
5476             needNotify = !privacyBundles.empty();
5477             break;
5478         }
5479         const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
5480         if (lastPrivacyBundles.size() != privacyBundles.size()) {
5481             TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
5482                   lastPrivacyBundles.size(), privacyBundles.size());
5483             needNotify = true;
5484             break;
5485         }
5486         for (const auto& bundle : lastPrivacyBundles) {
5487             if (privacyBundles.find(bundle) == privacyBundles.end()) {
5488                 needNotify = true;
5489                 break;
5490             }
5491         }
5492     } while (false);
5493 
5494     TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
5495           displayId, needNotify);
5496     if (needNotify) {
5497         reSendTimes = MAX_RESEND_TIMES;
5498         privacyBundleMap_[displayId] = privacyBundles;
5499     } else if (reSendTimes > 0) {
5500         needNotify = true;
5501         reSendTimes--;
5502         privacyBundleMap_[displayId] = privacyBundles;
5503     }
5504     return needNotify;
5505 }
5506 
UpdatePrivateStateAndNotify(uint32_t persistentId)5507 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
5508 {
5509     auto sceneSession = GetSceneSession(persistentId);
5510     if (sceneSession == nullptr) {
5511         TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
5512         return;
5513     }
5514 
5515     auto sessionProperty = sceneSession->GetSessionProperty();
5516     if (sessionProperty == nullptr) {
5517         TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
5518         return;
5519     }
5520     auto displayId = sessionProperty->GetDisplayId();
5521     std::unordered_set<std::string> privacyBundleList;
5522     GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5523     if (!JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
5524         return;
5525     }
5526 
5527     std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
5528     ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5529         !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
5530     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
5531     if (!bundleListForNotify.empty()) {
5532         TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
5533     }
5534     for (const auto& bundle : bundleListForNotify) {
5535         TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
5536               displayId, bundle.c_str());
5537     }
5538 }
5539 
UpdatePrivateStateAndNotifyForAllScreens()5540 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
5541 {
5542     auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
5543     for (auto& iter : screenProperties) {
5544         auto displayId = iter.first;
5545         std::unordered_set<std::string> privacyBundleList;
5546         GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5547 
5548         ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5549             !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
5550     }
5551 }
5552 
GetSceneSessionPrivacyModeBundles(DisplayId displayId, std::unordered_set<std::string>& privacyBundles)5553 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
5554     std::unordered_set<std::string>& privacyBundles)
5555 {
5556     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5557     for (const auto& item : sceneSessionMap_) {
5558         sptr<SceneSession> sceneSession = item.second;
5559         if (sceneSession == nullptr) {
5560             TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
5561             continue;
5562         }
5563         auto sessionProperty = sceneSession->GetSessionProperty();
5564         if (sessionProperty == nullptr) {
5565             TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
5566             continue;
5567         }
5568         auto currentDisplayId = sessionProperty->GetDisplayId();
5569         if (displayId != currentDisplayId) {
5570             continue;
5571         }
5572         bool isForeground =  sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5573             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
5574         if (isForeground && sceneSession->GetParentSession() != nullptr) {
5575             isForeground = isForeground &&
5576                 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
5577                 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
5578         }
5579         bool isPrivate = sessionProperty->GetPrivacyMode() ||
5580             sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
5581         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
5582         if ((isForeground || IsSystemWindowVisible) && isPrivate) {
5583             if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
5584                 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
5585             } else {
5586                 TLOGW(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
5587                 privacyBundles.insert(sceneSession->GetWindowName());
5588             }
5589         }
5590     }
5591 }
5592 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)5593 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5594 {
5595     if (sceneSession == nullptr) {
5596         WLOGFE("session is nullptr");
5597         return;
5598     }
5599     sceneSession->SetSessionStateChangeNotifyManagerListener(
5600         [this](int32_t persistentId, const SessionState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
5601             OnSessionStateChange(persistentId, state);
5602         });
5603     WLOGFD("success");
5604 }
5605 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)5606 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5607 {
5608     if (sceneSession == nullptr) {
5609         WLOGFE("session is nullptr");
5610         return;
5611     }
5612     sceneSession->SetSessionInfoChangeNotifyManagerListener([this](int32_t persistentId) {
5613         NotifyWindowInfoChangeFromSession(persistentId);
5614     });
5615 }
5616 
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)5617 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5618 {
5619     if (sceneSession == nullptr) {
5620         WLOGFE("session is nullptr");
5621         return;
5622     }
5623     sceneSession->SetRequestFocusStatusNotifyManagerListener(
5624         [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
5625             RequestFocusStatus(persistentId, isFocused, byForeground, reason);
5626         });
5627     WLOGFD("success");
5628 }
5629 
RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)5630 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
5631 {
5632     GetStateFromManagerFunc func = [this](const ManagerState key) {
5633         switch (key) {
5634             case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
5635                 return this->IsScreenLocked();
5636                 break;
5637             default:
5638                 return false;
5639                 break;
5640         }
5641     };
5642     if (sceneSession == nullptr) {
5643         WLOGFE("session is nullptr");
5644         return;
5645     }
5646     sceneSession->SetGetStateFromManagerListener(func);
5647     WLOGFD("success");
5648 }
5649 
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)5650 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5651 {
5652     SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
5653         const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
5654         if (sceneSession == nullptr || property == nullptr) {
5655             TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
5656             return;
5657         }
5658         switch (action) {
5659             case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
5660                 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
5661                 break;
5662             case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
5663             case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
5664             case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
5665             case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
5666             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
5667             case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
5668                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5669                 break;
5670             case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
5671                 SetBrightness(sceneSession, property->GetBrightness());
5672                 break;
5673             case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
5674             case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
5675                 UpdatePrivateStateAndNotify(property->GetPersistentId());
5676                 break;
5677             case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
5678                 CheckAndNotifyWaterMarkChangedResult();
5679                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5680                 break;
5681             case WSPropertyChangeAction::ACTION_UPDATE_MODE:
5682                 if (sceneSession->GetSessionProperty() != nullptr) {
5683                     ProcessWindowModeType();
5684                 }
5685                 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5686                 break;
5687             case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5688                 HandleHideNonSystemFloatingWindows(property, sceneSession);
5689                 break;
5690             case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
5691                 FlushWindowInfoToMMI();
5692                 break;
5693             default:
5694                 break;
5695         }
5696     };
5697     if (sceneSession != nullptr) {
5698         sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
5699     }
5700 }
5701 
OnSessionStateChange( int32_t persistentId, const SessionState& state)5702 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
5703     int32_t persistentId, const SessionState& state)
5704 {
5705     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
5706     WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
5707     auto sceneSession = GetSceneSession(persistentId);
5708     if (sceneSession == nullptr) {
5709         WLOGFD("session is nullptr");
5710         return;
5711     }
5712     switch (state) {
5713         case SessionState::STATE_FOREGROUND:
5714             ProcessFocusWhenForeground(sceneSession);
5715             if (!IsSessionVisibleForeground(sceneSession)) {
5716                 sceneSession->SetPostProcessProperty(true);
5717                 break;
5718             }
5719             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
5720             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
5721             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
5722             UpdatePrivateStateAndNotify(persistentId);
5723             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5724                 ProcessSubSessionForeground(sceneSession);
5725             }
5726             break;
5727         case SessionState::STATE_BACKGROUND:
5728             NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
5729             RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
5730             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
5731             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
5732             HandleKeepScreenOn(sceneSession, false);
5733             UpdatePrivateStateAndNotify(persistentId);
5734             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5735                 ProcessSubSessionBackground(sceneSession);
5736             }
5737             break;
5738         case SessionState::STATE_CONNECT:
5739             SetSessionSnapshotSkipForAppProcess(sceneSession);
5740             SetSessionSnapshotSkipForAppBundleName(sceneSession);
5741             SetSessionWatermarkForAppProcess(sceneSession);
5742             break;
5743         case SessionState::STATE_DISCONNECT:
5744             if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
5745                 RemoveProcessSnapshotSkip(sceneSession->GetCallingPid());
5746                 RemoveProcessWatermarkPid(sceneSession->GetCallingPid());
5747             }
5748             break;
5749         default:
5750             break;
5751     }
5752     ProcessWindowModeType();
5753 }
5754 
ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)5755 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
5756 {
5757     auto persistentId = sceneSession->GetPersistentId();
5758     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5759         persistentId == focusedSessionId_) {
5760         if (needBlockNotifyFocusStatusUntilForeground_) {
5761             needBlockNotifyUnfocusStatus_ = false;
5762             needBlockNotifyFocusStatusUntilForeground_ = false;
5763             NotifyFocusStatus(sceneSession, true);
5764         }
5765     } else if (!sceneSession->IsFocusedOnShow()) {
5766         sceneSession->SetFocusedOnShow(true);
5767     } else {
5768         if (Session::IsScbCoreEnabled()) {
5769             ProcessFocusWhenForegroundScbCore(sceneSession);
5770         } else {
5771             RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5772         }
5773     }
5774 }
5775 
ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)5776 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
5777 {
5778     if (IsSessionVisibleForeground(sceneSession)) {
5779         if (sceneSession->IsFocusableOnShow()) {
5780             RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
5781         } else {
5782             sceneSession->SetFocusableOnShow(true);
5783         }
5784     } else {
5785         PostProcessFocusState state = {true, true, true, FocusChangeReason::APP_FOREGROUND};
5786         sceneSession->SetPostProcessFocusState(state);
5787     }
5788 }
5789 
ProcessWindowModeType()5790 void SceneSessionManager::ProcessWindowModeType()
5791 {
5792     if (isScreenLocked_) {
5793         return;
5794     }
5795     NotifyRSSWindowModeTypeUpdate();
5796 }
5797 
IsSmallFoldProduct()5798 static bool IsSmallFoldProduct()
5799 {
5800     static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
5801     if (foldScreenType.empty()) {
5802         TLOGE(WmsLogTag::DEFAULT, "foldScreenType is empty");
5803         return false;
5804     }
5805     return foldScreenType[0] == '2';
5806 }
5807 
IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)5808 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
5809 {
5810     auto sessionProperty = sceneSession->GetSessionProperty();
5811     if (sessionProperty == nullptr) {
5812         TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
5813         return false;
5814     }
5815     ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5816     return sessionProperty->GetDisplayId() != defaultScreenId;
5817 }
5818 
CheckWindowModeType()5819 WindowModeType SceneSessionManager::CheckWindowModeType()
5820 {
5821     bool inSplit = false;
5822     bool inFloating = false;
5823     bool fullScreen = false;
5824     bool isSmallFold = IsSmallFoldProduct();
5825     {
5826         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5827         for (const auto& session : sceneSessionMap_) {
5828             if (session.second == nullptr ||
5829                 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
5830                 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
5831                 continue;
5832             }
5833             if (isSmallFold && IsInSecondaryScreen(session.second)) {
5834                 continue;
5835             }
5836             auto mode = session.second->GetWindowMode();
5837             if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
5838                 inSplit = true;
5839             }
5840             if (mode == WindowMode::WINDOW_MODE_FLOATING) {
5841                 inFloating = true;
5842             }
5843             if (WindowHelper::IsFullScreenWindow(mode)) {
5844                 fullScreen = true;
5845             }
5846         }
5847     }
5848 
5849     WindowModeType type;
5850     if (inSplit) {
5851         if (inFloating) {
5852             type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
5853         } else {
5854             type = WindowModeType::WINDOW_MODE_SPLIT;
5855         }
5856     } else {
5857         if (inFloating) {
5858             if (fullScreen) {
5859                 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
5860             } else {
5861                 type = WindowModeType::WINDOW_MODE_FLOATING;
5862             }
5863         } else if (fullScreen) {
5864             type = WindowModeType::WINDOW_MODE_FULLSCREEN;
5865         } else {
5866             type = WindowModeType::WINDOW_MODE_OTHER;
5867         }
5868     }
5869     return type;
5870 }
5871 
NotifyRSSWindowModeTypeUpdate()5872 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
5873 {
5874     WindowModeType type = CheckWindowModeType();
5875     if (lastWindowModeType_ == type) {
5876         return;
5877     }
5878     lastWindowModeType_ = type;
5879     TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
5880         static_cast<uint8_t>(type));
5881     SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
5882 }
5883 
ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)5884 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
5885 {
5886     if (sceneSession == nullptr) {
5887         WLOGFD("session is nullptr");
5888         return;
5889     }
5890     std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
5891     for (const auto& subSession : sceneSession->GetSubSession()) {
5892         if (subSession == nullptr) {
5893             TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
5894             continue;
5895         }
5896         if (subSession->IsTopmost()) {
5897             modalVec.push_back(subSession);
5898             TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
5899             continue;
5900         }
5901         const auto& state = subSession->GetSessionState();
5902         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5903             TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
5904             continue;
5905         }
5906         RequestSessionFocus(subSession->GetPersistentId(), true);
5907         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5908         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
5909     }
5910 
5911     for (const auto& modal : modalVec) {
5912         if (modal == nullptr) {
5913             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
5914             continue;
5915         }
5916         const auto& state = modal->GetSessionState();
5917         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5918             TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
5919             continue;
5920         }
5921         auto modalSession = GetSceneSession(modal->GetPersistentId());
5922         if (modalSession == nullptr) {
5923             TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
5924             continue;
5925         }
5926         NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5927         if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
5928             needBlockNotifyUnfocusStatus_ = false;
5929             needBlockNotifyFocusStatusUntilForeground_ = false;
5930             NotifyFocusStatus(modalSession, true);
5931         }
5932         HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
5933     }
5934 }
5935 
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)5936 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5937 {
5938     // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
5939     sptr<SceneSession> mainSession = nullptr;
5940     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5941         mainSession = sceneSession;
5942     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5943         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5944     }
5945     if (mainSession == nullptr) {
5946         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5947         return WSError::WS_DO_NOTHING;
5948     }
5949 
5950     std::vector<sptr<SceneSession>> topmostVec;
5951     for (auto subSession : mainSession->GetSubSession()) {
5952         if (subSession && subSession->IsTopmost()) {
5953             topmostVec.push_back(subSession);
5954         }
5955     }
5956     if (std::find_if(topmostVec.begin(), topmostVec.end(),
5957         [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5958         != topmostVec.end()) {
5959             TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
5960             return WSError::WS_OK;
5961     }
5962     WSError ret = WSError::WS_DO_NOTHING;
5963     for (auto topmostSession : topmostVec) {
5964         if (topmostSession == nullptr) {
5965             continue;
5966         }
5967         // no need to consider order, since rule of zOrder
5968         if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
5969             ret = WSError::WS_OK;
5970         }
5971     }
5972     return ret;
5973 }
5974 
ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)5975 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5976 {
5977     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
5978     sptr<SceneSession> mainSession = nullptr;
5979     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5980         mainSession = sceneSession;
5981     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5982         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5983     }
5984     if (mainSession == nullptr) {
5985         TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5986         return WSError::WS_DO_NOTHING;
5987     }
5988     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
5989     if (std::find_if(dialogVec.begin(), dialogVec.end(),
5990         [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5991         != dialogVec.end()) {
5992             TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
5993             return WSError::WS_OK;
5994     }
5995     WSError ret = WSError::WS_DO_NOTHING;
5996     for (auto dialog : dialogVec) {
5997         if (dialog == nullptr) {
5998             continue;
5999         }
6000         // no need to consider order, since rule of zOrder
6001         if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
6002             ret = WSError::WS_OK;
6003         }
6004     }
6005     return ret;
6006 }
6007 
ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)6008 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
6009 {
6010     if (sceneSession == nullptr) {
6011         WLOGFD("session is nullptr");
6012         return;
6013     }
6014     for (const auto& subSession : sceneSession->GetSubSession()) {
6015         if (subSession == nullptr) {
6016             WLOGFD("sub session is nullptr");
6017             continue;
6018         }
6019         const auto& state = subSession->GetSessionState();
6020         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6021             WLOGFD("sub session is not active");
6022             continue;
6023         }
6024         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6025         HandleKeepScreenOn(subSession, false);
6026         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
6027     }
6028     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
6029     for (const auto& dialog : dialogVec) {
6030         if (dialog == nullptr) {
6031             TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
6032             continue;
6033         }
6034         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
6035         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6036         HandleKeepScreenOn(dialogSession, false);
6037         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
6038     }
6039     for (const auto& toastSession : sceneSession->GetToastSession()) {
6040         if (toastSession == nullptr) {
6041             TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
6042             continue;
6043         }
6044         const auto& state = toastSession->GetSessionState();
6045         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6046             TLOGD(WmsLogTag::WMS_TOAST, "toast session is not active");
6047             continue;
6048         }
6049         NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6050         HandleKeepScreenOn(toastSession, false);
6051         UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
6052         toastSession->SetActive(false);
6053         toastSession->BackgroundTask();
6054     }
6055 }
6056 
SetWindowFlags(const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)6057 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
6058     const sptr<WindowSessionProperty>& property)
6059 {
6060     if (sceneSession == nullptr) {
6061         WLOGFD("session is nullptr");
6062         return WSError::WS_ERROR_NULLPTR;
6063     }
6064     auto sessionProperty = sceneSession->GetSessionProperty();
6065     if (sessionProperty == nullptr) {
6066         return WSError::WS_ERROR_NULLPTR;
6067     }
6068     uint32_t flags = property->GetWindowFlags();
6069     uint32_t oldFlags = sessionProperty->GetWindowFlags();
6070     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6071         (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6072         !property->GetSystemCalling()) {
6073             WLOGFE("Set window flags permission denied");
6074             return WSError::WS_ERROR_NOT_SYSTEM_APP;
6075     }
6076     sessionProperty->SetWindowFlags(flags);
6077     CheckAndNotifyWaterMarkChangedResult();
6078     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6079         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6080     }
6081     WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
6082     return WSError::WS_OK;
6083 }
6084 
CheckAndNotifyWaterMarkChangedResult()6085 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
6086 {
6087     bool currentWaterMarkShowState = false;
6088     {
6089         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6090         for (const auto& iter: sceneSessionMap_) {
6091             auto& session = iter.second;
6092             if (!session) {
6093                 continue;
6094             }
6095             auto sessionProperty = session->GetSessionProperty();
6096             if (!sessionProperty) {
6097                 continue;
6098             }
6099             bool hasWaterMark = sessionProperty->GetWindowFlags() &
6100                 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
6101             bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
6102             if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
6103                 currentWaterMarkShowState = true;
6104                 break;
6105             }
6106         }
6107         if (combinedExtWindowFlags_.waterMarkFlag) {
6108             TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
6109             currentWaterMarkShowState = true;
6110         }
6111     }
6112     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
6113         lastWaterMarkShowState_ = currentWaterMarkShowState;
6114         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
6115     }
6116 }
6117 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)6118 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
6119 {
6120     WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
6121     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
6122     return WSError::WS_OK;
6123 }
6124 
ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const6125 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
6126 {
6127     if (!bundleMgr_) {
6128         WLOGFE("bundle manager is nullptr.");
6129         return;
6130     }
6131 
6132     AAFwk::Want want;
6133     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
6134     auto uid = abilityInfo.uid;
6135     want.SetParam("uid", uid);
6136     bundleMgr_->ProcessPreload(want);
6137 }
6138 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)6139 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
6140 {
6141     auto scnSession = GetSceneSession(persistentId);
6142     if (scnSession == nullptr) {
6143         TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
6144         return;
6145     }
6146 
6147     const auto& sessionInfo = scnSession->GetSessionInfo();
6148     if (IsAtomicServiceFreeInstall(sessionInfo)) {
6149         TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
6150             scnSession->GetPersistentId(), scnSession->GetWindowType());
6151         FillSessionInfo(scnSession);
6152     }
6153 
6154     TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
6155         scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
6156         sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6157     auto abilityInfoPtr = sessionInfo.abilityInfo;
6158     if (abilityInfoPtr == nullptr) {
6159         TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is null, Id: %{public}d", persistentId);
6160         return;
6161     }
6162 
6163     [this, persistentId] {
6164         auto task = [persistentId] {
6165             AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6166         };
6167         WLOGI("Post CompleteFirstFrameDrawing task. Id: %{public}d", persistentId);
6168         eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6169     }();
6170 
6171     auto task = [this, abilityInfoPtr, scnSession, persistentId] {
6172         if (!scnSession->GetSessionInfo().isSystem_ && !(abilityInfoPtr->excludeFromMissions)) {
6173             WLOGD("NotifyCreated, id: %{public}d", persistentId);
6174             listenerController_->NotifySessionCreated(persistentId);
6175         }
6176         ProcessPreload(*abilityInfoPtr);
6177     };
6178     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6179 }
6180 
NotifySessionMovedToFront(int32_t persistentId)6181 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6182 {
6183     auto sceneSession = GetSceneSession(persistentId);
6184     if (sceneSession == nullptr) {
6185         WLOGFE("session is invalid with %{public}d", persistentId);
6186         return;
6187     }
6188     WLOGFI("id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6189            sceneSession->GetSessionInfo().isSystem_);
6190     if (!sceneSession->GetSessionInfo().isSystem_ &&
6191         sceneSession->GetSessionInfo().abilityInfo &&
6192         !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6193         listenerController_->NotifySessionMovedToFront(persistentId);
6194     }
6195 }
6196 
SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)6197 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6198 {
6199     WLOGFI("label: %{public}s", label.c_str());
6200     auto task = [this, &token, &label]() {
6201         auto sceneSession = FindSessionByToken(token);
6202         if (sceneSession == nullptr) {
6203             WLOGFI("fail to find session by token");
6204             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6205         }
6206         sceneSession->SetSessionLabel(label);
6207         WLOGI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6208             sceneSession->GetSessionInfo().isSystem_);
6209         if (!sceneSession->GetSessionInfo().isSystem_) {
6210             WLOGD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6211             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6212         }
6213         return WSError::WS_OK;
6214     };
6215     return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6216 }
6217 
SetSessionIcon(const sptr<IRemoteObject>& token, const std::shared_ptr<Media::PixelMap>& icon)6218 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6219     const std::shared_ptr<Media::PixelMap>& icon)
6220 {
6221     WLOGFI("Enter");
6222     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6223         WLOGFE("The caller is not system-app, can not use system-api");
6224         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6225     }
6226 
6227     auto task = [this, &token, &icon]() {
6228         auto sceneSession = FindSessionByToken(token);
6229         if (sceneSession == nullptr) {
6230             WLOGFI("fail to find session by token");
6231             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6232         }
6233         sceneSession->SetSessionIcon(icon);
6234         WLOGI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6235             sceneSession->GetSessionInfo().isSystem_);
6236         if (!sceneSession->GetSessionInfo().isSystem_ &&
6237             sceneSession->GetSessionInfo().abilityInfo &&
6238             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6239             WLOGD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6240             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6241         }
6242         return WSError::WS_OK;
6243     };
6244     return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6245 }
6246 
IsValidSessionIds( const std::vector<int32_t>& sessionIds, std::vector<bool>& results)6247 WSError SceneSessionManager::IsValidSessionIds(
6248     const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6249 {
6250     WLOGFI("Enter");
6251     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6252     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6253         auto search = sceneSessionMap_.find(sessionIds.at(i));
6254         if (search == sceneSessionMap_.end() || search->second == nullptr) {
6255             results.push_back(false);
6256             continue;
6257         }
6258         results.push_back(true);
6259     }
6260     return WSError::WS_OK;
6261 }
6262 
RegisterSessionListener(const sptr<ISessionListener>& listener)6263 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6264 {
6265     WLOGFI("in");
6266     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6267         WLOGFE("not system-app, can not use system-api");
6268         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6269     }
6270     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6271         TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
6272         return WSError::WS_ERROR_INVALID_PERMISSION;
6273     }
6274     auto task = [this, &listener] {
6275         WSError ret = listenerController_->AddSessionListener(listener);
6276         // app continue report for distributed scheduled service
6277         SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6278             static_cast<int32_t>(ret));
6279         return ret;
6280     };
6281     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6282 }
6283 
UnRegisterSessionListener(const sptr<ISessionListener>& listener)6284 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6285 {
6286     WLOGFI("in");
6287     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6288         WLOGFE("not system-app, can not use system-api");
6289         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6290     }
6291     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6292         TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
6293         return WSError::WS_ERROR_INVALID_PERMISSION;
6294     }
6295     auto task = [this, &listener] {
6296         listenerController_->DelSessionListener(listener);
6297         return WSError::WS_OK;
6298     };
6299     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6300 }
6301 
GetSessionInfos(const std::string& deviceId, int32_t numMax, std::vector<SessionInfoBean>& sessionInfos)6302 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6303                                              std::vector<SessionInfoBean>& sessionInfos)
6304 {
6305     WLOGFI("Enter num max %{public}d", numMax);
6306     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6307         WLOGFE("The caller is not system-app, can not use system-api");
6308         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6309     }
6310     if (!SessionPermission::VerifySessionPermission()) {
6311         WLOGFE("The caller has not permission granted");
6312         return WSError::WS_ERROR_INVALID_PERMISSION;
6313     }
6314     auto task = [this, &deviceId, numMax, &sessionInfos]() {
6315         if (CheckIsRemote(deviceId)) {
6316             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6317             if (ret != ERR_OK) {
6318                 return WSError::WS_ERROR_INVALID_PARAM;
6319             } else {
6320                 return WSError::WS_OK;
6321             }
6322         }
6323         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6324         std::vector<sptr<SceneSession>> sceneSessionInfos;
6325         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6326         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6327             auto sceneSession = iter->second;
6328             if (sceneSession == nullptr) {
6329                 WLOGFE("session is nullptr");
6330                 continue;
6331             }
6332             auto sessionInfo = sceneSession->GetSessionInfo();
6333             if (sessionInfo.isSystem_) {
6334                 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
6335                 continue;
6336             }
6337             auto want = sessionInfo.want;
6338             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
6339                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6340                     sceneSession->GetPersistentId());
6341                 continue;
6342             }
6343             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
6344                 break;
6345             }
6346             WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
6347                 sessionInfo.bundleName_.c_str());
6348             sceneSessionInfos.emplace_back(sceneSession);
6349         }
6350         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
6351     };
6352     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
6353 }
6354 
GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)6355 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
6356 {
6357     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
6358     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
6359         TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
6360         return WSError::WS_ERROR_INVALID_PERMISSION;
6361     }
6362     if (pid < 0) {
6363         return WSError::WS_ERROR_INVALID_PARAM;
6364     }
6365     auto task = [this, pid, &windowStates] {
6366         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6367         for (const auto& [_, sceneSession] : sceneSessionMap_) {
6368             if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
6369                 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6370                 MainWindowState windowState;
6371                 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
6372                 windowState.isVisible_ = sceneSession->GetRSVisible();
6373                 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
6374                 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
6375                 windowStates.emplace_back(windowState);
6376             }
6377         }
6378         return WSError::WS_OK;
6379     };
6380     return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
6381 }
6382 
GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax, std::vector<SessionInfoBean>& sessionInfos)6383 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
6384                                                std::vector<SessionInfoBean>& sessionInfos)
6385 {
6386     TLOGI(WmsLogTag::DEFAULT, "begin");
6387     int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
6388     if (result != ERR_OK) {
6389         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6390         return result;
6391     }
6392     return ERR_OK;
6393 }
6394 
GetSessionInfo(const std::string& deviceId, int32_t persistentId, SessionInfoBean& sessionInfo)6395 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
6396                                             int32_t persistentId, SessionInfoBean& sessionInfo)
6397 {
6398     WLOGFI("id %{public}d", persistentId);
6399     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6400         WLOGFE("The caller is not system-app, can not use system-api");
6401         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6402     }
6403     if (!SessionPermission::VerifySessionPermission()) {
6404         WLOGFE("The caller has not permission granted");
6405         return WSError::WS_ERROR_INVALID_PERMISSION;
6406     }
6407     auto task = [this, &deviceId, persistentId, &sessionInfo]() {
6408         if (CheckIsRemote(deviceId)) {
6409             int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
6410             if (ret != ERR_OK) {
6411                 return WSError::WS_ERROR_INVALID_PARAM;
6412             } else {
6413                 return WSError::WS_OK;
6414             }
6415         }
6416         std::map<int32_t, sptr<SceneSession>>::iterator iter;
6417         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6418         iter = sceneSessionMap_.find(persistentId);
6419         if (iter != sceneSessionMap_.end()) {
6420             auto sceneSession = iter->second;
6421             if (sceneSession == nullptr) {
6422                 WLOGFE("session: %{public}d is nullptr", persistentId);
6423                 return WSError::WS_ERROR_INVALID_PARAM;
6424             }
6425             auto sceneSessionInfo = sceneSession->GetSessionInfo();
6426             if (sceneSessionInfo.isSystem_) {
6427                 WLOGFD("sessionId: %{public}d  isSystemScene", persistentId);
6428                 return WSError::WS_ERROR_INVALID_PARAM;
6429             }
6430             auto want = sceneSessionInfo.want;
6431             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
6432                 want->GetElement().GetBundleName().empty()) {
6433                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6434                     persistentId);
6435                 return WSError::WS_ERROR_INTERNAL_ERROR;
6436             }
6437             WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
6438                 sceneSessionInfo.bundleName_.c_str());
6439             return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
6440         } else {
6441             WLOGFW("sessionId: %{public}d not found", persistentId);
6442             return WSError::WS_ERROR_INVALID_PARAM;
6443         }
6444     };
6445     return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
6446 }
6447 
GetSessionInfoByContinueSessionId(const std::string& continueSessionId, SessionInfoBean& sessionInfo)6448 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
6449     SessionInfoBean& sessionInfo)
6450 {
6451     TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
6452         continueSessionId.c_str());
6453     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6454         TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
6455         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6456     }
6457     if (!SessionPermission::VerifySessionPermission()) {
6458         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
6459         return WSError::WS_ERROR_INVALID_PERMISSION;
6460     }
6461     auto task = [this, continueSessionId, &sessionInfo]() {
6462         WSError ret = WSError::WS_ERROR_INVALID_SESSION;
6463         {
6464             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6465             for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
6466                 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
6467                     ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
6468                     break;
6469                 }
6470             }
6471         }
6472 
6473         TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
6474         // app continue report for distributed scheduled service
6475         SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
6476             static_cast<int32_t>(ret));
6477         return ret;
6478     };
6479     return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
6480 }
6481 
GetRemoteSessionInfo(const std::string& deviceId, int32_t persistentId, SessionInfoBean& sessionInfo)6482 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
6483                                               int32_t persistentId, SessionInfoBean& sessionInfo)
6484 {
6485     WLOGFI("GetRemoteSessionInfoFromDms begin");
6486     std::vector<SessionInfoBean> sessionVector;
6487     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
6488     if (result != ERR_OK) {
6489         return result;
6490     }
6491     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
6492         if (iter->id == persistentId) {
6493             sessionInfo = *iter;
6494             return ERR_OK;
6495         }
6496     }
6497     WLOGFW("missionId not found");
6498     return ERR_INVALID_VALUE;
6499 }
6500 
CheckIsRemote(const std::string& deviceId)6501 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
6502 {
6503     if (deviceId.empty()) {
6504         WLOGFI("CheckIsRemote: deviceId is empty.");
6505         return false;
6506     }
6507     std::string localDeviceId;
6508     if (!GetLocalDeviceId(localDeviceId)) {
6509         WLOGFE("CheckIsRemote: get local deviceId failed");
6510         return false;
6511     }
6512     if (localDeviceId == deviceId) {
6513         WLOGFI("CheckIsRemote: deviceId is local.");
6514         return false;
6515     }
6516     WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
6517     return true;
6518 }
6519 
GetLocalDeviceId(std::string& localDeviceId)6520 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
6521 {
6522     auto localNode = std::make_unique<NodeBasicInfo>();
6523     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
6524     if (errCode != ERR_OK) {
6525         WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
6526         return false;
6527     }
6528     if (localNode != nullptr) {
6529         localDeviceId = localNode->networkId;
6530         WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
6531         return true;
6532     }
6533     WLOGFE("localDeviceId null");
6534     return false;
6535 }
6536 
AnonymizeDeviceId(const std::string& deviceId)6537 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
6538 {
6539     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
6540         return EMPTY_DEVICE_ID;
6541     }
6542     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
6543     anonDeviceId.append("******");
6544     return anonDeviceId;
6545 }
6546 
DumpSessionAll(std::vector<std::string>& infos)6547 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
6548 {
6549     WLOGFI("Dump all session.");
6550     if (!SessionPermission::IsSystemCalling()) {
6551         WLOGFE("DumpSessionAll permission denied!");
6552         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6553     }
6554 
6555     auto task = [this, &infos]() {
6556         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6557         infos.push_back(dumpInfo);
6558         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6559         for (const auto &item : sceneSessionMap_) {
6560             auto& session = item.second;
6561             if (session) {
6562                 session->DumpSessionInfo(infos);
6563             }
6564         }
6565         return WSError::WS_OK;
6566     };
6567 
6568     return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
6569 }
6570 
DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)6571 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
6572 {
6573     WLOGFI("Dump session with id %{public}d", persistentId);
6574     if (!SessionPermission::IsSystemCalling()) {
6575         WLOGFE("DumpSessionWithId permission denied!");
6576         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6577     }
6578 
6579     auto task = [this, persistentId, &infos]() {
6580         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6581         infos.push_back(dumpInfo);
6582         auto session = GetSceneSession(persistentId);
6583         if (session) {
6584             session->DumpSessionInfo(infos);
6585         } else {
6586             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
6587         }
6588         return WSError::WS_OK;
6589     };
6590 
6591     return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
6592 }
6593 
GetAllAbilityInfos( const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)6594 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
6595     const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6596 {
6597     if (bundleMgr_ == nullptr) {
6598         WLOGFE("bundleMgr_ is nullptr");
6599         return WSError::WS_ERROR_NULLPTR;
6600     }
6601     auto elementName = want.GetElement();
6602     int32_t ret{0};
6603     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6604         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6605         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6606         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6607         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6608         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6609     std::vector<AppExecFwk::BundleInfo> bundleInfos;
6610     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
6611         WLOGFD("want is empty queryAllAbilityInfos");
6612         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
6613         if (ret) {
6614             WLOGFE("Query all ability infos from BMS failed!");
6615             return WSError::WS_ERROR_INVALID_PARAM;
6616         }
6617     } else if (!elementName.GetBundleName().empty()) {
6618         AppExecFwk::BundleInfo bundleInfo;
6619         WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
6620         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
6621         if (ret) {
6622             WLOGFE("Query ability info from BMS failed!");
6623             return WSError::WS_ERROR_INVALID_PARAM;
6624         }
6625         bundleInfos.push_back(bundleInfo);
6626     } else {
6627         WLOGFE("invalid want:%{public}s", want.ToString().c_str());
6628         return WSError::WS_ERROR_INVALID_PARAM;
6629     }
6630     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6631 }
6632 
GetBatchAbilityInfos( const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)6633 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
6634     const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6635 {
6636     if (bundleMgr_ == nullptr) {
6637         TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
6638         return WSError::WS_ERROR_NULLPTR;
6639     }
6640     if (bundleNames.empty()) {
6641         TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
6642         return WSError::WS_ERROR_INVALID_PARAM;
6643     }
6644     auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6645                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6646                 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6647                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6648                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6649                 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
6650     std::vector<AppExecFwk::BundleInfo> bundleInfos;
6651     auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
6652     if (ret) {
6653         TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
6654         return WSError::WS_ERROR_INVALID_PARAM;
6655     }
6656     return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6657 }
6658 
GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo>& bundleInfos, std::vector<SCBAbilityInfo>& scbAbilityInfos)6659 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo>& bundleInfos,
6660     std::vector<SCBAbilityInfo>& scbAbilityInfos)
6661 {
6662     if (bundleInfos.empty()) {
6663         WLOGFE("bundleInfos is empty");
6664         return WSError::WS_ERROR_INVALID_PARAM;
6665     }
6666     for (auto bundleInfo: bundleInfos) {
6667         auto hapModulesList = bundleInfo.hapModuleInfos;
6668         auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
6669         if (hapModulesList.empty()) {
6670             WLOGFD("hapModulesList is empty");
6671             continue;
6672         }
6673         for (auto hapModule: hapModulesList) {
6674             auto abilityInfoList = hapModule.abilityInfos;
6675             for (auto abilityInfo : abilityInfoList) {
6676                 SCBAbilityInfo scbAbilityInfo;
6677                 scbAbilityInfo.abilityInfo_ = abilityInfo;
6678                 scbAbilityInfo.sdkVersion_ = sdkVersion;
6679                 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6680                 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6681                 scbAbilityInfos.push_back(scbAbilityInfo);
6682             }
6683         }
6684     }
6685     return WSError::WS_OK;
6686 }
6687 
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)6688 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
6689 {
6690     if (abilityInfo.orientationId == 0) {
6691         return;
6692     }
6693     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
6694     if (resConfig == nullptr) {
6695         TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
6696         return;
6697     }
6698     std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
6699         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
6700     if (resourceMgr == nullptr) {
6701         TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
6702         return;
6703     }
6704     std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
6705     if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
6706         TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
6707     }
6708     std::string orientation;
6709     auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
6710     if (ret != Global::Resource::RState::SUCCESS) {
6711         TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
6712             static_cast<int32_t>(ret), abilityInfo.orientationId);
6713         return;
6714     }
6715     if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
6716         TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
6717         return;
6718     }
6719     abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
6720 }
6721 
TerminateSessionNew( const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)6722 WSError SceneSessionManager::TerminateSessionNew(
6723     const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
6724 {
6725     if (info == nullptr) {
6726         TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
6727         return WSError::WS_ERROR_INVALID_PARAM;
6728     }
6729     TLOGI(WmsLogTag::WMS_LIFE,
6730         "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
6731         info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
6732     int32_t callingPid = IPCSkeleton::GetCallingPid();
6733     uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
6734     auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
6735         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
6736         if (sceneSession == nullptr) {
6737             TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
6738             return WSError::WS_ERROR_INVALID_PARAM;
6739         }
6740         const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
6741         if (!pidCheck &&
6742             !SessionPermission::VerifyPermissionByCallerToken(callerToken,
6743                 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6744             TLOGE(WmsLogTag::WMS_LIFE,
6745                 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
6746                 sceneSession->GetCallingPid(), callingPid);
6747             return WSError::WS_ERROR_INVALID_PERMISSION;
6748         }
6749         WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
6750         return errCode;
6751     };
6752     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
6753 }
6754 
SetVmaCacheStatus(bool flag)6755 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
6756 {
6757     WLOGFI("flag: %{public}d", flag);
6758     RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
6759     return WSError::WS_OK;
6760 }
6761 
GetSessionSnapshot(const std::string& deviceId, int32_t persistentId, SessionSnapshot& snapshot, bool isLowResolution)6762 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
6763                                                 SessionSnapshot& snapshot, bool isLowResolution)
6764 {
6765     WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
6766     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6767         WLOGFE("The caller is not system-app, can not use system-api");
6768         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6769     }
6770     if (!SessionPermission::VerifySessionPermission()) {
6771         WLOGFE("The caller has not permission granted");
6772         return WSError::WS_ERROR_INVALID_PERMISSION;
6773     }
6774     auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
6775         if (CheckIsRemote(deviceId)) {
6776             int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
6777             if (ret != ERR_OK) {
6778                 return WSError::WS_ERROR_INVALID_PARAM;
6779             } else {
6780                 return WSError::WS_OK;
6781             }
6782         }
6783         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6784         if (!sceneSession) {
6785             WLOGFE("fail to find session by persistentId: %{public}d", persistentId);
6786             return WSError::WS_ERROR_INVALID_PARAM;
6787         }
6788         auto sessionInfo = sceneSession->GetSessionInfo();
6789         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6790             WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6791                    sceneSession->GetPersistentId());
6792         }
6793         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
6794         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
6795         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
6796         auto oriSnapshot = sceneSession->Snapshot();
6797         if (oriSnapshot != nullptr) {
6798             if (isLowResolution) {
6799                 OHOS::Media::InitializationOptions options;
6800                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
6801                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
6802                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
6803                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
6804             } else {
6805                 snapshot.snapshot = oriSnapshot;
6806             }
6807         }
6808         return WSError::WS_OK;
6809     };
6810     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
6811 }
6812 
GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)6813 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
6814 {
6815     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
6816         TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
6817         return WMError::WM_ERROR_NOT_SYSTEM_APP;
6818     }
6819     auto task = [this, persistentId, &snapshot]() {
6820         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6821         if (!sceneSession) {
6822             TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
6823             return WMError::WM_ERROR_INVALID_PARAM;
6824         }
6825         auto sessionInfo = sceneSession->GetSessionInfo();
6826         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6827             TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6828                 sceneSession->GetPersistentId());
6829         }
6830         snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
6831         snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
6832         snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
6833         auto oriSnapshot = sceneSession->Snapshot();
6834         if (oriSnapshot != nullptr) {
6835             snapshot.snapshot = oriSnapshot;
6836             return WMError::WM_OK;
6837         }
6838         return WMError::WM_ERROR_NULLPTR;
6839     };
6840     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
6841 }
6842 
GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)6843 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
6844 {
6845     if (!SessionPermission::IsSACalling()) {
6846         TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
6847         return WSError::WS_ERROR_INVALID_PERMISSION;
6848     }
6849     TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
6850     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6851     if (sceneSession == nullptr) {
6852         TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
6853         return WSError::WS_ERROR_NULLPTR;
6854     }
6855     return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
6856 }
6857 
GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId, AAFwk::MissionSnapshot& sessionSnapshot)6858 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
6859                                                       AAFwk::MissionSnapshot& sessionSnapshot)
6860 {
6861     TLOGI(WmsLogTag::DEFAULT, "begin");
6862     int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
6863         sessionId, sessionSnapshot);
6864     if (result != ERR_OK) {
6865         TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6866         return result;
6867     }
6868     return ERR_OK;
6869 }
6870 
GetCollaboratorByType(int32_t collaboratorType)6871 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
6872 {
6873     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
6874     std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
6875     auto iter = collaboratorMap_.find(collaboratorType);
6876     if (iter == collaboratorMap_.end()) {
6877         TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
6878         return collaborator;
6879     }
6880     collaborator = iter->second;
6881     if (collaborator == nullptr) {
6882         TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
6883     }
6884     return collaborator;
6885 }
6886 
RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)6887 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
6888 {
6889     wptr<SceneSession> weakSceneSession(sceneSession);
6890     auto task = [this, weakSceneSession]() {
6891         auto scnSession = weakSceneSession.promote();
6892         if (scnSession == nullptr) {
6893             WLOGFE("session is nullptr");
6894             return WSError::WS_ERROR_NULLPTR;
6895         }
6896         auto persistentId = scnSession->GetPersistentId();
6897         if (!GetSceneSession(persistentId)) {
6898             WLOGFE("session is invalid with %{public}d", persistentId);
6899             return WSError::WS_ERROR_INVALID_SESSION;
6900         }
6901         auto sessionInfo = scnSession->GetSessionInfo();
6902         auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
6903         if (!abilitySessionInfo) {
6904             TLOGE(WmsLogTag::WMS_MAIN,
6905                 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
6906             return WSError::WS_ERROR_NULLPTR;
6907         }
6908         if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
6909             scnSession->SetActive(false);
6910         } else if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::FOREGROUND)) {
6911             scnSession->SetActive(true);
6912         } else {
6913             WLOGFE("wrong callState_");
6914         }
6915         TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
6916             sessionInfo.callState_, persistentId);
6917         bool isColdStart = false;
6918         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
6919         if (isColdStart) {
6920             TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
6921                 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
6922             scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
6923             scnSession->ResetSessionConnectState();
6924         }
6925         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
6926         return WSError::WS_OK;
6927     };
6928     std::string taskName = "RequestSceneSessionByCall:PID:" +
6929         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
6930     taskScheduler_->PostAsyncTask(task, taskName);
6931     return WSError::WS_OK;
6932 }
6933 
StartAbilityBySpecified(const SessionInfo& sessionInfo)6934 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
6935 {
6936     auto task = [this, sessionInfo]() {
6937         WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
6938             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6939         AAFwk::Want want;
6940         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
6941         if (sessionInfo.want != nullptr) {
6942             want.SetParams(sessionInfo.want->GetParams());
6943             want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int>(sessionInfo.screenId_));
6944         }
6945         AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
6946     };
6947 
6948     taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
6949 }
6950 
NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)6951 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
6952 {
6953     TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
6954     if (pid == -1) {
6955         TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
6956         return;
6957     }
6958     int32_t ret = HiSysEventWrite(
6959         HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
6960         "WINDOW_STATE_ERROR",
6961         HiviewDFX::HiSysEvent::EventType::FAULT,
6962         "PID", pid,
6963         "PERSISTENT_ID", persistentId);
6964     if (ret != 0) {
6965         TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
6966     }
6967     auto task = [this, pid] {
6968         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6969         for (const auto& [_, sceneSession] : sceneSessionMap_) {
6970             if (!sceneSession || pid != sceneSession->GetCallingPid() ||
6971                 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6972                 continue;
6973             }
6974             auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6975             if (abilitySessionInfo) {
6976                 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
6977                     abilitySessionInfo->persistentId);
6978                 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
6979             }
6980         }
6981     };
6982     // delay 2000ms, wait for hidumper
6983     taskScheduler_->PostAsyncTask(task, __func__, 2000);
6984 }
6985 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)6986 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
6987 {
6988     if (!targetToken) {
6989         WLOGFE("Token is null, cannot find main window");
6990         return nullptr;
6991     }
6992 
6993     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6994     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
6995         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
6996             if (pair.second->IsTerminated()) {
6997                 return false;
6998             }
6999             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7000                 return pair.second->GetAbilityToken() == targetToken;
7001             }
7002             return false;
7003         });
7004     if (iter == sceneSessionMap_.end()) {
7005         WLOGFE("Cannot find session");
7006         return nullptr;
7007     }
7008     return iter->second;
7009 }
7010 
BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)7011 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
7012 {
7013     if (!SessionPermission::IsSystemCalling()) {
7014         TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
7015         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7016     }
7017     if (targetToken == nullptr) {
7018         TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
7019         return WSError::WS_ERROR_NULLPTR;
7020     }
7021 
7022     auto task = [this, persistentId, targetToken]() {
7023         auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
7024         if (scnSession == nullptr) {
7025             TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
7026             return WSError::WS_ERROR_NULLPTR;
7027         }
7028         if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
7029             TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
7030             return WSError::WS_OK;
7031         }
7032         scnSession->dialogTargetToken_ = targetToken;
7033         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
7034         if (parentSession == nullptr) {
7035             scnSession->NotifyDestroy();
7036             return WSError::WS_ERROR_INVALID_PARAM;
7037         }
7038         scnSession->SetParentSession(parentSession);
7039         scnSession->SetParentPersistentId(parentSession->GetPersistentId());
7040         UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
7041         TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
7042             persistentId, parentSession->GetPersistentId());
7043         return WSError::WS_OK;
7044     };
7045     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
7046 }
7047 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds, std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)7048 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7049     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7050 {
7051     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
7052 }
7053 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds, std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)7054 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7055     std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7056 {
7057     auto isSaCall = SessionPermission::IsSACalling();
7058     if (!isSaCall) {
7059         WLOGFE("The interface only support for sa call");
7060         return WMError::WM_ERROR_INVALID_PERMISSION;
7061     }
7062     auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
7063         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7064         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7065         for (auto missionId : missionIds) {
7066             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
7067             if (iter == sceneSessionMap_.end()) {
7068                 continue;
7069             }
7070             auto sceneSession = iter->second;
7071             if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
7072                 continue;
7073             }
7074             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
7075             if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
7076                 surfaceNodeIds.push_back(missionId);
7077                 continue;
7078             }
7079             if (sceneSession->GetLeashWinSurfaceNode()) {
7080                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
7081             }
7082         }
7083         return WMError::WM_OK;
7084     };
7085     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
7086 }
7087 
RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr<IWindowManagerAgent>& windowManagerAgent)7088 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
7089     const sptr<IWindowManagerAgent>& windowManagerAgent)
7090 {
7091     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7092         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7093         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7094         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7095         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
7096         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY) {
7097         if (!SessionPermission::IsSACalling()) {
7098             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7099             return WMError::WM_ERROR_INVALID_PERMISSION;
7100         }
7101     }
7102     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7103         TLOGD(WmsLogTag::DEFAULT, "permission denied");
7104         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7105     }
7106     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7107         WLOGFE("windowManagerAgent is null");
7108         return WMError::WM_ERROR_NULLPTR;
7109     }
7110     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7111     auto task = [this, windowManagerAgent, type, callingPid]() {
7112         return SessionManagerAgentController::GetInstance()
7113             .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7114     };
7115     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
7116 }
7117 
UnregisterWindowManagerAgent(WindowManagerAgentType type, const sptr<IWindowManagerAgent>& windowManagerAgent)7118 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
7119     const sptr<IWindowManagerAgent>& windowManagerAgent)
7120 {
7121     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7122         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7123         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7124         if (!SessionPermission::IsSystemCalling()) {
7125             WLOGFE("UnregisterWindowManagerAgent permission denied!");
7126             return WMError::WM_ERROR_NOT_SYSTEM_APP;
7127         }
7128     }
7129     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7130         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7131         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7132         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7133         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7134         if (!SessionPermission::IsSACalling()) {
7135             TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7136             return WMError::WM_ERROR_INVALID_PERMISSION;
7137         }
7138     }
7139     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7140         WLOGFE("windowManagerAgent is null");
7141         return WMError::WM_ERROR_NULLPTR;
7142     }
7143     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7144     auto task = [this, windowManagerAgent, type, callingPid]() {
7145         return SessionManagerAgentController::GetInstance()
7146             .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7147     };
7148     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7149 }
7150 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)7151 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7152 {
7153     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7154 }
7155 
UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)7156 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7157 {
7158     SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7159 }
7160 
StartWindowInfoReportLoop()7161 void SceneSessionManager::StartWindowInfoReportLoop()
7162 {
7163     WLOGFD("in");
7164     if (isReportTaskStart_) {
7165         WLOGFE("Report is ReportTask Start");
7166         return;
7167     }
7168     auto task = [this] {
7169         WindowInfoReporter::GetInstance().ReportRecordedInfos();
7170         ReportWindowProfileInfos();
7171         isReportTaskStart_ = false;
7172         StartWindowInfoReportLoop();
7173     };
7174     int64_t delayTime = 1000 * 60 * 60; // an hour.
7175     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7176     if (!ret) {
7177         WLOGFE("failed. task is WindowInfoReport");
7178         return;
7179     }
7180     isReportTaskStart_ = true;
7181 }
7182 
InitPersistentStorage()7183 void SceneSessionManager::InitPersistentStorage()
7184 {
7185     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7186         int32_t storageMode = -1;
7187         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7188         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7189             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7190             WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7191             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7192         }
7193     }
7194 }
7195 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)7196 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7197 {
7198     WLOGFD("Called.");
7199     if (!SessionPermission::IsSystemServiceCalling()) {
7200         WLOGFE("Only support for system service.");
7201         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7202     }
7203     auto task = [this, &infos]() {
7204         std::map<int32_t, sptr<SceneSession>>::iterator iter;
7205         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7206         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7207             sptr<SceneSession> sceneSession = iter->second;
7208             if (sceneSession == nullptr) {
7209                 WLOGFW("null scene session");
7210                 continue;
7211             }
7212             bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7213                 sceneSession->IsVisibleForAccessibility() :
7214                 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7215             WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7216                 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7217                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7218                 sceneSession->GetSessionState(), isVisibleForAccessibility);
7219             if (isVisibleForAccessibility) {
7220                 FillWindowInfo(infos, iter->second);
7221             }
7222         }
7223         return WMError::WM_OK;
7224     };
7225     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7226 }
7227 
CheckUnreliableWindowType(WindowType windowType)7228 static bool CheckUnreliableWindowType(WindowType windowType)
7229 {
7230     if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7231         windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7232         windowType == WindowType::WINDOW_TYPE_TOAST) {
7233         return true;
7234     }
7235     TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7236     return false;
7237 }
7238 
FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession, std::vector<sptr<UnreliableWindowInfo>>& infos)7239 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7240     std::vector<sptr<UnreliableWindowInfo>>& infos)
7241 {
7242     if (sceneSession == nullptr) {
7243         TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7244         return;
7245     }
7246     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7247         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7248         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7249         TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7250         return;
7251     }
7252     sptr<UnreliableWindowInfo> info = sptr<UnreliableWindowInfo>::MakeSptr();
7253     info->windowId_ = sceneSession->GetPersistentId();
7254     WSRect windowRect = sceneSession->GetSessionRect();
7255     info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7256     info->zOrder_ = sceneSession->GetZOrder();
7257     info->floatingScale_ = sceneSession->GetFloatingScale();
7258     info->scaleX_ = sceneSession->GetScaleX();
7259     info->scaleY_ = sceneSession->GetScaleY();
7260     infos.emplace_back(info);
7261     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7262 }
7263 
GetUnreliableWindowInfo(int32_t windowId, std::vector<sptr<UnreliableWindowInfo>>& infos)7264 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
7265     std::vector<sptr<UnreliableWindowInfo>>& infos)
7266 {
7267     TLOGD(WmsLogTag::DEFAULT, "Called.");
7268     if (!SessionPermission::IsSystemServiceCalling()) {
7269         TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
7270         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7271     }
7272     auto task = [this, windowId, &infos]() {
7273         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7274         for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
7275             if (sceneSession == nullptr) {
7276                 TLOGW(WmsLogTag::DEFAULT, "null scene session");
7277                 continue;
7278             }
7279             if (sessionId == windowId) {
7280                 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
7281                 FillUnreliableWindowInfo(sceneSession, infos);
7282                 continue;
7283             }
7284             if (!sceneSession->GetRSVisible()) {
7285                 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
7286                 continue;
7287             }
7288             TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
7289                 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
7290                 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
7291                 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
7292             if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
7293                 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
7294                     "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
7295                 FillUnreliableWindowInfo(sceneSession, infos);
7296             }
7297         }
7298         return WMError::WM_OK;
7299     };
7300     return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
7301 }
7302 
NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)7303 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
7304 {
7305     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
7306     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7307     if (sceneSession == nullptr) {
7308         WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
7309         return;
7310     }
7311     wptr<SceneSession> weakSceneSession(sceneSession);
7312     if (processingFlushUIParams_.load()) {
7313         TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
7314         auto task = [this, weakSceneSession, type]() {
7315             auto sceneSession = weakSceneSession.promote();
7316             if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7317                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7318                 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7319             }
7320         };
7321         taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
7322         return;
7323     }
7324     auto task = [this, weakSceneSession, type]() {
7325         auto sceneSession = weakSceneSession.promote();
7326         NotifyAllAccessibilityInfo();
7327         if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7328             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7329             WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7330         }
7331     };
7332     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
7333     auto notifySceneInputTask = [weakSceneSession, type]() {
7334         auto sceneSession = weakSceneSession.promote();
7335         if (sceneSession == nullptr) {
7336             return;
7337         }
7338         SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
7339     };
7340     taskScheduler_->PostAsyncTask(notifySceneInputTask);
7341 }
7342 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos, const sptr<SceneSession>& sceneSession)7343 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
7344     const sptr<SceneSession>& sceneSession)
7345 {
7346     if (sceneSession == nullptr) {
7347         WLOGFW("null scene session.");
7348         return false;
7349     }
7350     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7351         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7352         sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7353         WLOGFD("filter gesture window.");
7354         return false;
7355     }
7356     sptr<AccessibilityWindowInfo> info = sptr<AccessibilityWindowInfo>::MakeSptr();
7357     if (sceneSession->GetSessionInfo().isSystem_) {
7358         info->wid_ = 1;
7359         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7360     } else {
7361         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7362     }
7363     info->uiNodeId_ = sceneSession->GetUINodeId();
7364     WSRect wsrect = sceneSession->GetSessionGlobalRect(); // only accessability and mmi need global
7365     info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
7366     info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
7367     info->type_ = sceneSession->GetWindowType();
7368     info->mode_ = sceneSession->GetWindowMode();
7369     info->layer_ = sceneSession->GetZOrder();
7370     info->scaleVal_ = sceneSession->GetFloatingScale();
7371     info->scaleX_ = sceneSession->GetScaleX();
7372     info->scaleY_ = sceneSession->GetScaleY();
7373     info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
7374     info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
7375     auto property = sceneSession->GetSessionProperty();
7376     if (property != nullptr) {
7377         info->displayId_ = property->GetDisplayId();
7378         info->isDecorEnable_ = property->IsDecorEnable();
7379     }
7380     infos.emplace_back(info);
7381     TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
7382         info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
7383     return true;
7384 }
7385 
GetSessionSnapshotFilePath(int32_t persistentId)7386 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
7387 {
7388     WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
7389     auto sceneSession = GetSceneSession(persistentId);
7390     if (sceneSession == nullptr) {
7391         WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
7392         return "";
7393     }
7394     wptr<SceneSession> weakSceneSession(sceneSession);
7395     auto task = [this, weakSceneSession]() {
7396         auto scnSession = weakSceneSession.promote();
7397         if (scnSession == nullptr) {
7398             WLOGFE("session is nullptr");
7399             return std::string("");
7400         }
7401         std::string filePath = scnSession->GetSessionSnapshotFilePath();
7402         return filePath;
7403     };
7404     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
7405 }
7406 
SelectSesssionFromMap(const uint64_t& surfaceId)7407 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
7408 {
7409     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7410     for (const auto &item : sceneSessionMap_) {
7411         auto sceneSession = item.second;
7412         if (sceneSession == nullptr) {
7413             continue;
7414         }
7415         if (sceneSession->GetSurfaceNode() == nullptr) {
7416             continue;
7417         }
7418         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
7419             return sceneSession;
7420         }
7421     }
7422     return nullptr;
7423 }
7424 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)7425 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
7426 {
7427     WLOGFD("WindowLayerInfoChangeCallback: entry");
7428     std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
7429 
7430     auto task = [this, weak]() {
7431         auto weakOcclusionData = weak.lock();
7432         if (weakOcclusionData == nullptr) {
7433             WLOGFE("weak occlusionData is nullptr");
7434             return;
7435         }
7436         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
7437         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
7438         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
7439         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
7440         if (currVisibleData.size() != 0) {
7441             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
7442         }
7443         if (visibilityChangeInfos.size() != 0) {
7444             DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
7445             CacVisibleWindowNum();
7446         }
7447 
7448         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
7449         if (currDrawingContentData.size() != 0) {
7450             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
7451         }
7452         if (drawingContentChangeInfos.size() != 0) {
7453             DealwithDrawingContentChange(drawingContentChangeInfos);
7454         }
7455     };
7456     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
7457 }
7458 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData, std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData, std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)7459 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
7460     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
7461     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
7462 {
7463     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
7464     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
7465         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
7466         switch (windowLayerState) {
7467             case WINDOW_ALL_VISIBLE:
7468             case WINDOW_SEMI_VISIBLE:
7469             case WINDOW_IN_VISIBLE:
7470                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
7471                 break;
7472             case WINDOW_LAYER_DRAWING:
7473                 currDrawingContentData.emplace_back(iter->first, true);
7474                 break;
7475             case WINDOW_LAYER_NO_DRAWING:
7476                 currDrawingContentData.emplace_back(iter->first, false);
7477                 break;
7478             default:
7479                 break;
7480         }
7481     }
7482 }
7483 
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)7484 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
7485     WindowVisibilityState visibleState,
7486     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7487     std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
7488     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7489 {
7490     if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
7491             visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7492         auto subSessions = GetSubSceneSession(session->GetWindowId());
7493         if (subSessions.empty()) {
7494             return;
7495         }
7496 
7497         RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
7498 
7499         for (const auto& subSession : subSessions) {
7500             if (subSession == nullptr) {
7501                 continue;
7502             }
7503             if (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData)) {
7504                 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
7505                     subSession->GetWindowId());
7506                 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
7507             }
7508         }
7509     }
7510 }
7511 
GetSessionRSVisible(const sptr<Session>& session, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7512 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
7513     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7514 {
7515     bool sessionRSVisible = false;
7516     for (const auto& [surfaceId, visibleState] : currVisibleData) {
7517         sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
7518         if (visibilitySession == nullptr) {
7519             continue;
7520         }
7521         if (session->GetWindowId() == visibilitySession->GetWindowId()) {
7522             if (visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7523                 sessionRSVisible = true;
7524             }
7525             break;
7526         }
7527     }
7528     return sessionRSVisible;
7529 }
7530 
SetSessionVisibilityInfo(const sptr<SceneSession>& session, WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo)7531 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
7532     WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
7533     std::string& visibilityInfo)
7534 {
7535     if (session == nullptr) {
7536         TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
7537         return;
7538     }
7539     session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7540     session->SetVisibilityState(visibleState);
7541     int32_t windowId = session->GetWindowId();
7542     if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
7543         session->NotifyWindowVisibility();
7544     }
7545     windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
7546         windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
7547 
7548     visibilityInfo +=
7549         "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
7550 }
7551 
RemoveDuplicateSubSession( const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo, std::vector<sptr<SceneSession>>& subSessions)7552 void SceneSessionManager::RemoveDuplicateSubSession(
7553     const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7554     std::vector<sptr<SceneSession>>& subSessions)
7555 {
7556     for (const auto& elem : visibilityChangeInfo) {
7557         uint64_t surfaceId = elem.first;
7558         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7559         if (session == nullptr) {
7560             continue;
7561         }
7562         for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
7563             auto subSession = *iterator;
7564             if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
7565                 iterator = subSessions.erase(iterator);
7566             } else {
7567                 ++iterator;
7568             }
7569         }
7570     }
7571 }
7572 
GetSubSceneSession(int32_t parentWindowId)7573 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
7574 {
7575     std::vector<sptr<SceneSession>> subSessions;
7576     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7577     for (const auto& iter : sceneSessionMap_) {
7578         auto sceneSession = iter.second;
7579         if (sceneSession == nullptr) {
7580             continue;
7581         }
7582         if (sceneSession->GetParentSession() != nullptr &&
7583             sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
7584             subSessions.push_back(sceneSession);
7585         }
7586     }
7587     return subSessions;
7588 }
7589 
GetWindowVisibilityChangeInfo( std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7590 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
7591     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7592 {
7593     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
7594     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
7595     uint32_t i, j;
7596     i = j = 0;
7597     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
7598         if (lastVisibleData_[i].first < currVisibleData[j].first) {
7599             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7600             i++;
7601         } else if (lastVisibleData_[i].first > currVisibleData[j].first &&
7602                 currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7603             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7604             j++;
7605         } else {
7606             if (lastVisibleData_[i].second != currVisibleData[j].second) {
7607                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7608             }
7609             i++;
7610             j++;
7611         }
7612     }
7613     for (; i < lastVisibleData_.size(); ++i) {
7614         visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7615     }
7616     for (; j < currVisibleData.size(); ++j) {
7617         if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7618             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7619         }
7620     }
7621     lastVisibleData_ = currVisibleData;
7622     return visibilityChangeInfo;
7623 }
7624 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7625 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
7626     visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7627 {
7628     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7629 #ifdef MEMMGR_WINDOW_ENABLE
7630     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7631 #endif
7632 
7633     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
7634     for (const auto& elem : visibilityChangeInfo) {
7635         uint64_t surfaceId = elem.first;
7636         WindowVisibilityState visibleState = elem.second;
7637         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7638         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7639         if (session == nullptr) {
7640             continue;
7641         }
7642         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
7643             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
7644             if (session->GetParentSession() != nullptr &&
7645                 !session->GetParentSession()->IsSessionForeground() &&
7646                 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
7647                 continue;
7648             }
7649         }
7650         SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
7651         UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
7652 #ifdef MEMMGR_WINDOW_ENABLE
7653         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
7654             session->GetCallingUid(), isVisible));
7655 #endif
7656         CheckAndNotifyWaterMarkChangedResult();
7657     }
7658     if (windowVisibilityInfos.size() != 0) {
7659         WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
7660             visibilityInfo.c_str());
7661         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7662     }
7663 #ifdef MEMMGR_WINDOW_ENABLE
7664     if (memMgrWindowInfos.size() != 0) {
7665         WLOGD("Notify memMgrWindowInfos changed start");
7666         taskScheduler_ ->AddExportTask("notifyMemMgr", [memMgrWindowInfos = std::move(memMgrWindowInfos)]() {
7667             Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7668         });
7669     }
7670 #endif
7671 }
7672 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>& drawingContentChangeInfo)7673 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
7674     drawingContentChangeInfo)
7675 {
7676     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
7677     for (const auto& elem : drawingContentChangeInfo) {
7678         uint64_t surfaceId = elem.first;
7679         bool drawingState = elem.second;
7680         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7681         if (session == nullptr) {
7682             continue;
7683         }
7684         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
7685             session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
7686         if (openDebugTrace_) {
7687             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
7688                 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
7689         }
7690         WLOGFD("drawing status changed pid:%{public}d, "
7691             "surfaceId:%{public}" PRIu64 ", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
7692     }
7693     if (windowDrawingContenInfos.size() != 0) {
7694         WLOGFD("Notify WindowDrawingContenInfo changed start");
7695         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
7696     }
7697 }
7698 
GetWindowDrawingContentChangeInfo( std::vector<std::pair<uint64_t, bool>> currDrawingContentData)7699 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
7700     std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
7701 {
7702     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
7703     for (const auto& data : currDrawingContentData) {
7704         uint64_t windowId = data.first;
7705         bool currentDrawingContentState = data.second;
7706         int32_t pid = 0;
7707         bool isChange = false;
7708         if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
7709             continue;
7710         } else {
7711             isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
7712         }
7713 
7714         if (isChange) {
7715             processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
7716         }
7717     }
7718     return processDrawingContentChangeInfo;
7719 }
7720 
GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)7721 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
7722 {
7723     bool preWindowDrawingState = true;
7724     sptr<SceneSession> session = SelectSesssionFromMap(windowId);
7725     if (session == nullptr) {
7726         return false;
7727     }
7728     pid = session->GetCallingPid();
7729     preWindowDrawingState = session->GetDrawingContentState();
7730     session->SetDrawingContentState(currentDrawingContentState);
7731     return preWindowDrawingState;
7732 }
7733 
GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)7734 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
7735 {
7736     bool isChange = true;
7737     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7738     for (const auto& item : sceneSessionMap_) {
7739         auto sceneSession = item.second;
7740         if (sceneSession == nullptr) {
7741             continue;
7742         }
7743         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
7744             windowId != sceneSession->GetSurfaceNode()->GetId()) {
7745                 if (sceneSession->GetDrawingContentState()) {
7746                     return false;
7747                 }
7748             }
7749         }
7750     return isChange;
7751 }
7752 
7753 
InitWithRenderServiceAdded()7754 void SceneSessionManager::InitWithRenderServiceAdded()
7755 {
7756     auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
7757         this->WindowLayerInfoChangeCallback(occlusiontionData);
7758     };
7759     WLOGI("RegisterWindowVisibilityChangeCallback");
7760     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
7761         WLOGFE("RegisterWindowVisibilityChangeCallback failed");
7762     }
7763 }
7764 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)7765 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
7766 {
7767     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
7768         WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
7769         return WMError::WM_ERROR_INVALID_PARAM;
7770     }
7771 
7772     auto task = [this, sceneType]() {
7773         WLOGFD("Set system animated scene %{public}d.", sceneType);
7774         bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
7775         if (!ret) {
7776             WLOGFE("Set system animated scene failed.");
7777         }
7778     };
7779     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
7780     return WMError::WM_OK;
7781 }
7782 
NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)7783 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
7784 {
7785     if (!SessionPermission::IsSystemCalling()) {
7786         TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
7787         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7788     }
7789     if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
7790         TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
7791         return WSError::WS_ERROR_INVALID_PERMISSION;
7792     }
7793     TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
7794         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
7795     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7796     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
7797         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
7798         WindowType::WINDOW_TYPE_APP_COMPONENT));
7799     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7800     return WSError::WS_OK;
7801 }
7802 
WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)7803 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
7804 {
7805     if (sceneSession == nullptr) {
7806         WLOGFE("sceneSession is nullptr!");
7807         return;
7808     }
7809     if (sceneSession->GetRSVisible()) {
7810         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7811 #ifdef MEMMGR_WINDOW_ENABLE
7812         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7813 #endif
7814         sceneSession->SetRSVisible(false);
7815         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7816         sceneSession->ClearExtWindowFlags();
7817         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
7818             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
7819             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
7820 #ifdef MEMMGR_WINDOW_ENABLE
7821         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
7822         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
7823 #endif
7824         WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
7825             sceneSession->GetWindowId(), sceneSession->GetRSVisible());
7826         CheckAndNotifyWaterMarkChangedResult();
7827         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7828 #ifdef MEMMGR_WINDOW_ENABLE
7829         WLOGD("Notify memMgrWindowInfos changed start");
7830         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7831 #endif
7832     }
7833 }
7834 
FindSessionByToken(const sptr<IRemoteObject>& token)7835 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
7836 {
7837     if (token == nullptr) {
7838         TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
7839         return nullptr;
7840     }
7841     sptr<SceneSession> session = nullptr;
7842     auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7843         if (pair.second == nullptr) {
7844             return false;
7845         }
7846         return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
7847     };
7848     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7849     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7850     if (iter != sceneSessionMap_.end()) {
7851         session = iter->second;
7852     }
7853     return session;
7854 }
7855 
FindSessionByAffinity(std::string affinity)7856 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
7857 {
7858     if (affinity.size() == 0) {
7859         WLOGFI("AbilityInfo affinity is empty");
7860         return nullptr;
7861     }
7862     sptr<SceneSession> session = nullptr;
7863     auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7864         if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
7865             return false;
7866         }
7867         return pair.second->GetSessionInfo().sessionAffinity == affinity;
7868     };
7869     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7870     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7871     if (iter != sceneSessionMap_.end()) {
7872         session = iter->second;
7873     }
7874     return session;
7875 }
7876 
PreloadInLakeApp(const std::string& bundleName)7877 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
7878 {
7879     WLOGFD("Enter name %{public}s", bundleName.c_str());
7880     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
7881     if (collaborator != nullptr) {
7882         WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
7883         collaborator->NotifyPreloadAbility(bundleName);
7884     }
7885 }
7886 
PendingSessionToForeground(const sptr<IRemoteObject>& token)7887 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
7888 {
7889     TLOGI(WmsLogTag::DEFAULT, "Enter");
7890     auto pid = IPCSkeleton::GetCallingRealPid();
7891     if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
7892         TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
7893         return WSError::WS_ERROR_INVALID_PERMISSION;
7894     }
7895 
7896     auto task = [this, &token]() {
7897         auto session = FindSessionByToken(token);
7898         if (session != nullptr) {
7899             return session->PendingSessionToForeground();
7900         }
7901         TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
7902         return WSError::WS_ERROR_INVALID_PARAM;
7903     };
7904     return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
7905 }
7906 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token, bool shouldBackToCaller)7907 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
7908     bool shouldBackToCaller)
7909 {
7910     auto task = [this, &token, shouldBackToCaller] {
7911         auto session = FindSessionByToken(token);
7912         if (session != nullptr) {
7913             return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
7914         }
7915         TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
7916         return WSError::WS_ERROR_INVALID_PARAM;
7917     };
7918     return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
7919 }
7920 
ClearDisplayStatusBarTemporarilyFlags()7921 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
7922 {
7923     for (auto persistentId : avoidAreaListenerSessionSet_) {
7924         auto sceneSession = GetSceneSession(persistentId);
7925         if (sceneSession == nullptr) {
7926             continue;
7927         }
7928         sceneSession->SetIsDisplayStatusBarTemporarily(false);
7929     }
7930 }
7931 
GetFocusSessionToken(sptr<IRemoteObject>& token)7932 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject>& token)
7933 {
7934     if (!SessionPermission::IsSACalling()) {
7935         WLOGFE("GetFocusSessionToken permission denied!");
7936         return WSError::WS_ERROR_INVALID_PERMISSION;
7937     }
7938     auto task = [this, &token]() {
7939         WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
7940         auto sceneSession = GetSceneSession(focusedSessionId_);
7941         if (sceneSession) {
7942             token = sceneSession->GetAbilityToken();
7943             if (token == nullptr) {
7944                 WLOGFE("token is nullptr");
7945                 return WSError::WS_ERROR_INVALID_PARAM;
7946             }
7947             return WSError::WS_OK;
7948         }
7949         return WSError::WS_ERROR_INVALID_SESSION;
7950     };
7951     return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
7952 }
7953 
GetFocusSessionElement(AppExecFwk::ElementName& element)7954 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
7955 {
7956     AppExecFwk::RunningProcessInfo info;
7957     auto pid = IPCSkeleton::GetCallingRealPid();
7958     DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
7959     if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
7960         WLOGFE("SystemCalling permission denied!");
7961         return WSError::WS_ERROR_INVALID_PERMISSION;
7962     }
7963     auto task = [this, &element]() {
7964         WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
7965         auto sceneSession = GetSceneSession(focusedSessionId_);
7966         if (sceneSession) {
7967             auto sessionInfo = sceneSession->GetSessionInfo();
7968             element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
7969                 sessionInfo.abilityName_, sessionInfo.moduleName_);
7970             return WSError::WS_OK;
7971         }
7972         return WSError::WS_ERROR_INVALID_SESSION;
7973     };
7974     return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
7975 }
7976 
UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)7977 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
7978 {
7979     const auto callingPid = IPCSkeleton::GetCallingRealPid();
7980     auto task = [this, persistentId, haveListener, callingPid]() {
7981         TLOGI(WmsLogTag::WMS_IMMS,
7982             "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
7983             persistentId, haveListener);
7984         auto sceneSession = GetSceneSession(persistentId);
7985         if (sceneSession == nullptr) {
7986             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
7987             return WSError::WS_DO_NOTHING;
7988         }
7989         if (callingPid != sceneSession->GetCallingPid()) {
7990             TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
7991             return WSError::WS_ERROR_INVALID_PERMISSION;
7992         }
7993         if (haveListener) {
7994             avoidAreaListenerSessionSet_.insert(persistentId);
7995             UpdateAvoidArea(persistentId);
7996         } else {
7997             lastUpdatedAvoidArea_.erase(persistentId);
7998             avoidAreaListenerSessionSet_.erase(persistentId);
7999         }
8000         return WSError::WS_OK;
8001     };
8002     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
8003 }
8004 
UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId, const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)8005 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
8006     const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
8007 {
8008     if (sceneSession == nullptr) {
8009         TLOGI(WmsLogTag::WMS_IMMS, "scene session null no need update avoid area");
8010         return false;
8011     }
8012     if (lastUpdatedAvoidArea_.find(persistentId) == lastUpdatedAvoidArea_.end()) {
8013         lastUpdatedAvoidArea_[persistentId] = {};
8014     }
8015 
8016     bool needUpdate = true;
8017     if (auto iter = lastUpdatedAvoidArea_[persistentId].find(avoidAreaType);
8018         iter != lastUpdatedAvoidArea_[persistentId].end()) {
8019         needUpdate = iter->second != avoidArea;
8020     } else {
8021         if (avoidArea.isEmptyAvoidArea()) {
8022             TLOGI(WmsLogTag::WMS_IMMS, "window %{public}d type %{public}d empty avoid area",
8023                 persistentId, avoidAreaType);
8024             needUpdate = false;
8025             return needUpdate;
8026         }
8027     }
8028     if (needUpdate) {
8029         lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
8030         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
8031     }
8032 
8033     return needUpdate;
8034 }
8035 
UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)8036 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
8037 {
8038     bool ret = true;
8039     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
8040         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
8041     for (auto& persistentId : avoidAreaListenerSessionSet_) {
8042         auto sceneSession = GetSceneSession(persistentId);
8043         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8044             continue;
8045         }
8046         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8047         ret = UpdateSessionAvoidAreaIfNeed(
8048             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8049         needUpdate = needUpdate || ret;
8050     }
8051 
8052     return;
8053 }
8054 
CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)8055 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
8056 {
8057     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
8058         !avoidArea.rightRect_.IsUninitializedRect()) {
8059         return false;
8060     }
8061     if (avoidArea.bottomRect_.IsUninitializedRect()) {
8062         return true;
8063     }
8064     auto diff =
8065         std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
8066     return isVisible && diff <= 1;
8067 }
8068 
UpdateNormalSessionAvoidArea( const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)8069 void SceneSessionManager::UpdateNormalSessionAvoidArea(
8070     const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
8071 {
8072     bool ret = true;
8073     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8074         TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
8075             persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
8076         needUpdate = false;
8077         return;
8078     }
8079     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8080         TLOGD(WmsLogTag::WMS_IMMS,
8081             "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
8082         needUpdate = false;
8083         return;
8084     }
8085     uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
8086     uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8087     for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
8088         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8089         if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
8090             !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8091                 sceneSession->GetSessionRect().height_)) {
8092             continue;
8093         }
8094         ret = UpdateSessionAvoidAreaIfNeed(
8095             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8096         needUpdate = needUpdate || ret;
8097     }
8098 
8099     return;
8100 }
8101 
NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)8102 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
8103 {
8104     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
8105     auto sceneSession = GetSceneSession(windowId);
8106     if (sceneSession == nullptr) {
8107         WLOGFW("window not exist: %{public}d", windowId);
8108         return;
8109     }
8110 
8111     wptr<SceneSession> weakSceneSession(sceneSession);
8112     WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
8113     auto task = [weakSceneSession, startMoving]() -> WSError {
8114         auto scnSession = weakSceneSession.promote();
8115         if (scnSession == nullptr) {
8116             WLOGFW("session is null");
8117             return WSError::WS_ERROR_NULLPTR;
8118         }
8119         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8120         return WSError::WS_OK;
8121     };
8122     return taskScheduler_->PostAsyncTask(task);
8123 }
8124 
UpdateAvoidArea(int32_t persistentId)8125 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8126 {
8127     auto task = [this, persistentId] {
8128         bool needUpdate = false;
8129         auto sceneSession = GetSceneSession(persistentId);
8130         if (sceneSession == nullptr) {
8131             TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8132             return;
8133         }
8134         WindowType type = sceneSession->GetWindowType();
8135         if (sceneSession->IsImmersiveType()) {
8136             UpdateAvoidSessionAvoidArea(type, needUpdate);
8137         } else {
8138             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8139         }
8140         if (needUpdate) {
8141             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8142         }
8143         return;
8144     };
8145     taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8146     return;
8147 }
8148 
UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)8149 void SceneSessionManager::UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)
8150 {
8151     auto task = [this, persistentId, type] {
8152         auto sceneSession = GetSceneSession(persistentId);
8153         if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8154             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is nullptr or invisible", persistentId);
8155             return;
8156         }
8157         if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8158             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d has no listener, no need update", persistentId);
8159             return;
8160         }
8161         if (sceneSession->IsImmersiveType()) {
8162             TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is immersive type", persistentId);
8163             return;
8164         }
8165         auto avoidArea = sceneSession->GetAvoidAreaByType(type);
8166         if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && !CheckAvoidAreaForAINavigationBar(
8167             isAINavigationBarVisible_, avoidArea, sceneSession->GetSessionRect().height_)) {
8168             return;
8169         }
8170         UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, type);
8171     };
8172     taskScheduler_->PostAsyncTask(task, "UpdateAvoidAreaByType:PID:" + std::to_string(persistentId));
8173 }
8174 
UpdateGestureBackEnabled(int32_t persistentId)8175 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8176 {
8177     auto task = [this, persistentId] {
8178         auto sceneSession = GetSceneSession(persistentId);
8179         if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8180             TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8181             return;
8182         }
8183         auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8184         if (needEnableGestureBack) {
8185             gestureBackEnableWindowIdSet_.erase(persistentId);
8186         } else {
8187             gestureBackEnableWindowIdSet_.insert(persistentId);
8188         }
8189         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8190             sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8191             (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8192              sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8193             enterRecent_.load() || !sceneSession->IsFocused()) {
8194             needEnableGestureBack = true;
8195         }
8196         if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8197             gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8198                 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8199         } else {
8200             TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8201         }
8202     };
8203     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8204 }
8205 
UpdateOccupiedAreaIfNeed(const int32_t& persistentId)8206 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8207 {
8208     auto task = [this, persistentId]() {
8209         sptr<SceneSession> keyboardSession = nullptr;
8210         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8211         for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8212             auto sceneSession = item->second;
8213             if (sceneSession != nullptr &&
8214                 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8215                 keyboardSession = sceneSession;
8216                 break;
8217             }
8218         }
8219         if (keyboardSession == nullptr) {
8220             TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8221             return;
8222         }
8223         if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8224             return;
8225         }
8226 
8227         keyboardSession->OnCallingSessionUpdated();
8228         return;
8229     };
8230     taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8231     return;
8232 }
8233 
NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)8234 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8235 {
8236     TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8237         isVisible, persistentId);
8238     auto task = [this, persistentId, isVisible] {
8239         auto sceneSession = GetSceneSession(persistentId);
8240         if (sceneSession == nullptr) {
8241             TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8242             return;
8243         }
8244         sceneSession->SetIsStatusBarVisible(isVisible);
8245     };
8246     taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8247     return WSError::WS_OK;
8248 }
8249 
NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)8250 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8251 {
8252     WLOGFI("isVisible: %{public}u, "
8253         "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8254         isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8255     auto task = [this, isVisible, barArea, displayId]() {
8256         bool isNeedNotify = isAINavigationBarVisible_ != isVisible;
8257         {
8258             std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8259             bool isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8260                 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8261                 currAINavigationBarAreaMap_[displayId] != barArea;
8262             if (isNeedUpdate) {
8263                 isAINavigationBarVisible_ = isVisible;
8264                 currAINavigationBarAreaMap_.clear();
8265                 currAINavigationBarAreaMap_[displayId] = barArea;
8266             }
8267             if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8268                 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8269                 currAINavigationBarAreaMap_[displayId] = WSRect();
8270             }
8271         }
8272         if (isNeedNotify) {
8273             WLOGFI("NotifyAINavigationBar: enter: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8274                 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8275             for (auto persistentId : avoidAreaListenerSessionSet_) {
8276                 NotifySessionAINavigationBarChange(persistentId);
8277             }
8278         }
8279     };
8280     taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
8281     return WSError::WS_OK;
8282 }
8283 
NotifySessionAINavigationBarChange(int32_t persistentId)8284 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
8285 {
8286     auto sceneSession = GetSceneSession(persistentId);
8287     if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8288         return;
8289     }
8290     AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8291     if (!CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8292         sceneSession->GetSessionRect().height_)) {
8293         return;
8294     }
8295     WLOGFI("NotifyAINavigationBarShowStatus: persistentId: %{public}d, "
8296         "{%{public}d,%{public}d,%{public}d,%{public}d}", persistentId,
8297         avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
8298         avoidArea.bottomRect_.width_, avoidArea.bottomRect_.height_);
8299     UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
8300         AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8301 }
8302 
GetAINavigationBarArea(uint64_t displayId)8303 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
8304 {
8305     std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8306     if (currAINavigationBarAreaMap_.count(displayId) == 0) {
8307         return {};
8308     }
8309     return currAINavigationBarAreaMap_[displayId];
8310 }
8311 
UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)8312 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
8313 {
8314     const auto callingPid = IPCSkeleton::GetCallingRealPid();
8315     auto task = [this, persistentId, haveListener, callingPid]() {
8316         TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
8317             persistentId, haveListener);
8318         auto sceneSession = GetSceneSession(persistentId);
8319         if (sceneSession == nullptr) {
8320             TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
8321             return WSError::WS_DO_NOTHING;
8322         }
8323         if (callingPid != sceneSession->GetCallingPid()) {
8324             TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
8325             return WSError::WS_ERROR_INVALID_PERMISSION;
8326         }
8327         if (haveListener) {
8328             touchOutsideListenerSessionSet_.insert(persistentId);
8329         } else {
8330             touchOutsideListenerSessionSet_.erase(persistentId);
8331         }
8332         return WSError::WS_OK;
8333     };
8334     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
8335 }
8336 
UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)8337 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
8338 {
8339     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
8340     auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
8341         WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
8342             persistentId, haveListener);
8343         auto sceneSession = GetSceneSession(persistentId);
8344         if (sceneSession == nullptr) {
8345             WLOGFD("sceneSession is nullptr.");
8346             return WSError::WS_DO_NOTHING;
8347         }
8348         if (callingPid != sceneSession->GetCallingPid()) {
8349             TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
8350             return WSError::WS_ERROR_INVALID_PERMISSION;
8351         }
8352         if (haveListener) {
8353             windowVisibilityListenerSessionSet_.insert(persistentId);
8354             sceneSession->NotifyWindowVisibility();
8355         } else {
8356             windowVisibilityListenerSessionSet_.erase(persistentId);
8357         }
8358         return WSError::WS_OK;
8359     };
8360     return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
8361 }
8362 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)8363 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
8364 {
8365     processVirtualPixelRatioChangeFunc_ = func;
8366     WLOGFI("SetVirtualPixelRatioChangeListener");
8367 }
8368 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)8369 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8370     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8371 {
8372     if (displayInfo == nullptr) {
8373         WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
8374         return;
8375     }
8376     auto task = [this, displayInfo]() {
8377         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8378         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
8379             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
8380             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
8381                 displayInfo->GetWidth(), displayInfo->GetHeight()
8382             };
8383             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
8384         }
8385         for (const auto &item : sceneSessionMap_) {
8386             auto scnSession = item.second;
8387             if (scnSession == nullptr) {
8388                 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
8389                 continue;
8390             }
8391             if (scnSession->GetSessionProperty() != nullptr &&
8392                 scnSession->GetSessionProperty()->GetDisplayId() != displayInfo->GetDisplayId()) {
8393                 continue;
8394             }
8395             SessionInfo sessionInfo = scnSession->GetSessionInfo();
8396             if (sessionInfo.isSystem_) {
8397                 continue;
8398             }
8399             if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8400                 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
8401                 scnSession->UpdateDensity();
8402                 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
8403                     "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
8404                     scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8405             }
8406         }
8407         UpdateDisplayRegion(displayInfo);
8408         return WSError::WS_OK;
8409     };
8410     taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
8411 }
8412 
ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)8413 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8414     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8415 {
8416     if (displayInfo == nullptr) {
8417         WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
8418         return;
8419     }
8420     auto task = [this, displayInfo]() {
8421         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8422         for (const auto &item : sceneSessionMap_) {
8423             auto scnSession = item.second;
8424             if (scnSession == nullptr) {
8425                 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
8426                 continue;
8427             }
8428             if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8429                 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
8430                 continue;
8431             }
8432             if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
8433                 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
8434                 scnSession->GetRotation() != displayInfo->GetRotation()) {
8435                 scnSession->UpdateRotationAvoidArea();
8436                 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
8437                     "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
8438                     item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8439             }
8440             scnSession->SetRotation(displayInfo->GetRotation());
8441             scnSession->UpdateOrientation();
8442         }
8443         UpdateDisplayRegion(displayInfo);
8444         return WSError::WS_OK;
8445     };
8446     taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
8447 }
8448 
ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)8449 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
8450 {
8451     if (displayInfo == nullptr) {
8452         TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
8453         return;
8454     }
8455 
8456     auto task = [displayInfo]() -> WSError {
8457         ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
8458             displayInfo->GetScaleX(),
8459             displayInfo->GetScaleY(),
8460             displayInfo->GetPivotX(),
8461             displayInfo->GetPivotY(),
8462             displayInfo->GetTranslateX(),
8463             displayInfo->GetTranslateY());
8464         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
8465         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
8466         return WSError::WS_OK;
8467     };
8468     return taskScheduler_->PostAsyncTask(task);
8469 }
8470 
OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)8471 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8472     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8473 {
8474     WLOGFD("type: %{public}u", type);
8475     switch (type) {
8476         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
8477             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
8478                 displayInfo, displayInfoMap, type);
8479             break;
8480         }
8481         case DisplayStateChangeType::UPDATE_ROTATION: {
8482             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
8483                 displayInfo, displayInfoMap, type);
8484             break;
8485         }
8486         case DisplayStateChangeType::UPDATE_SCALE: {
8487             SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
8488             break;
8489         }
8490         default:
8491             return;
8492     }
8493 }
8494 
OnScreenshot(DisplayId displayId)8495 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
8496 {
8497     SceneSessionManager::GetInstance().OnScreenshot(displayId);
8498 }
8499 
OnScreenshot(DisplayId displayId)8500 void SceneSessionManager::OnScreenshot(DisplayId displayId)
8501 {
8502     auto task = [this, displayId]() {
8503         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8504         for (const auto& iter : sceneSessionMap_) {
8505             auto sceneSession = iter.second;
8506             if (sceneSession == nullptr) {
8507                 continue;
8508             }
8509             auto state = sceneSession->GetSessionState();
8510             if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
8511                 sceneSession->NotifyScreenshot();
8512             }
8513         }
8514     };
8515     taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
8516 }
8517 
ClearSession(int32_t persistentId)8518 WSError SceneSessionManager::ClearSession(int32_t persistentId)
8519 {
8520     WLOGFI("id: %{public}d", persistentId);
8521     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8522         WLOGFE("The caller is not system-app, can not use system-api");
8523         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8524     }
8525     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8526         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8527         return WSError::WS_ERROR_INVALID_PERMISSION;
8528     }
8529     auto task = [this, persistentId]() {
8530         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8531         return ClearSession(sceneSession);
8532     };
8533     taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
8534     return WSError::WS_OK;
8535 }
8536 
ClearSession(sptr<SceneSession> sceneSession)8537 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
8538 {
8539     WLOGFD("Enter");
8540     if (sceneSession == nullptr) {
8541         WLOGFE("session is nullptr");
8542         return WSError::WS_ERROR_INVALID_SESSION;
8543     }
8544     if (!IsSessionClearable(sceneSession)) {
8545         WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
8546         return WSError::WS_ERROR_INVALID_SESSION;
8547     }
8548     const WSError errCode = sceneSession->Clear();
8549     return errCode;
8550 }
8551 
ClearAllSessions()8552 WSError SceneSessionManager::ClearAllSessions()
8553 {
8554     WLOGFI("Enter");
8555     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8556         WLOGFE("The caller is not system-app, can not use system-api");
8557         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8558     }
8559     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8560         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8561         return WSError::WS_ERROR_INVALID_PERMISSION;
8562     }
8563     auto task = [this]() {
8564         std::vector<sptr<SceneSession>> sessionVector;
8565         GetAllClearableSessions(sessionVector);
8566         for (uint32_t i = 0; i < sessionVector.size(); i++) {
8567             ClearSession(sessionVector[i]);
8568         }
8569         return WSError::WS_OK;
8570     };
8571     taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
8572     return WSError::WS_OK;
8573 }
8574 
GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)8575 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
8576 {
8577     WLOGFI("Enter");
8578     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8579     for (const auto &item : sceneSessionMap_) {
8580         auto scnSession = item.second;
8581         if (IsSessionClearable(scnSession)) {
8582             sessionVector.push_back(scnSession);
8583         }
8584     }
8585 }
8586 
LockSession(int32_t sessionId)8587 WSError SceneSessionManager::LockSession(int32_t sessionId)
8588 {
8589     WLOGFI("id: %{public}d", sessionId);
8590     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8591         WLOGFE("The caller is not system-app, can not use system-api");
8592         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8593     }
8594     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8595         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8596         return WSError::WS_ERROR_INVALID_PERMISSION;
8597     }
8598     auto task = [this, sessionId]() {
8599         auto sceneSession = GetSceneSession(sessionId);
8600         if (sceneSession == nullptr) {
8601             WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
8602             return WSError::WS_ERROR_INVALID_PARAM;
8603         }
8604         sceneSession->SetSessionInfoLockedState(true);
8605         return WSError::WS_OK;
8606     };
8607     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
8608 }
8609 
UnlockSession(int32_t sessionId)8610 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
8611 {
8612     WLOGFI("id: %{public}d", sessionId);
8613     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8614         WLOGFE("The caller is not system-app, can not use system-api");
8615         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8616     }
8617     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8618         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8619         return WSError::WS_ERROR_INVALID_PERMISSION;
8620     }
8621     auto task = [this, sessionId]() {
8622         auto sceneSession = GetSceneSession(sessionId);
8623         if (sceneSession == nullptr) {
8624             WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
8625             return WSError::WS_ERROR_INVALID_PARAM;
8626         }
8627         sceneSession->SetSessionInfoLockedState(false);
8628         return WSError::WS_OK;
8629     };
8630     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
8631 }
8632 
MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)8633 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
8634 {
8635     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8636     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8637         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8638         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8639     }
8640     if (!SessionPermission::VerifySessionPermission()) {
8641         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8642         return WSError::WS_ERROR_INVALID_PERMISSION;
8643     }
8644 
8645     return WSError::WS_OK;
8646 }
8647 
MoveSessionsToBackground(const std::vector<int32_t>& sessionIds, std::vector<int32_t>& result)8648 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
8649     std::vector<int32_t>& result)
8650 {
8651     TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8652     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8653         TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8654         return WSError::WS_ERROR_NOT_SYSTEM_APP;
8655     }
8656     if (!SessionPermission::VerifySessionPermission()) {
8657         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8658         return WSError::WS_ERROR_INVALID_PERMISSION;
8659     }
8660 
8661     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
8662     return WSError::WS_OK;
8663 }
8664 
IsSessionClearable(sptr<SceneSession> scnSession)8665 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
8666 {
8667     if (scnSession == nullptr) {
8668         WLOGFI("scnSession is nullptr");
8669         return false;
8670     }
8671     SessionInfo sessionInfo = scnSession->GetSessionInfo();
8672     if (sessionInfo.abilityInfo == nullptr) {
8673         WLOGFI("scnSession abilityInfo is nullptr");
8674         return false;
8675     }
8676     if (sessionInfo.abilityInfo->excludeFromMissions) {
8677         WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
8678         return false;
8679     }
8680     if (sessionInfo.abilityInfo->unclearableMission) {
8681         WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
8682         return false;
8683     }
8684     if (sessionInfo.isSystem_) {
8685         WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
8686         return false;
8687     }
8688     if (sessionInfo.lockedState) {
8689         WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
8690         return false;
8691     }
8692 
8693     return true;
8694 }
8695 
RegisterIAbilityManagerCollaborator(int32_t type, const sptr<AAFwk::IAbilityManagerCollaborator>& impl)8696 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
8697     const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
8698 {
8699     WLOGFI("type: %{public}d", type);
8700     auto isSaCall = SessionPermission::IsSACalling();
8701     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8702         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8703         return WSError::WS_ERROR_INVALID_PERMISSION;
8704     }
8705     if (!CheckCollaboratorType(type)) {
8706         WLOGFW("collaborator register failed, invalid type.");
8707         return WSError::WS_ERROR_INVALID_TYPE;
8708     }
8709     if (impl == nullptr) {
8710         TLOGE(WmsLogTag::DEFAULT, "Collaborator is nullptr");
8711         return WSError::WS_ERROR_NULLPTR;
8712     }
8713     if (impl->AsObject() == nullptr || !impl->AsObject()->AddDeathRecipient(collaboratorDeathRecipient_)) {
8714         TLOGE(WmsLogTag::DEFAULT, "Failed to add collaborator death recipient");
8715         return WSError::WS_ERROR_IPC_FAILED;
8716     }
8717     {
8718         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8719         collaboratorMap_[type] = impl;
8720     }
8721     auto task = [this] {
8722         if (abilityManagerCollaboratorRegisteredFunc_) {
8723             abilityManagerCollaboratorRegisteredFunc_();
8724         }
8725     };
8726     taskScheduler_->PostTask(task, __func__);
8727     return WSError::WS_OK;
8728 }
8729 
UnregisterIAbilityManagerCollaborator(int32_t type)8730 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
8731 {
8732     WLOGFI("type: %{public}d", type);
8733     auto isSaCall = SessionPermission::IsSACalling();
8734     if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8735         TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8736         return WSError::WS_ERROR_INVALID_PERMISSION;
8737     }
8738     if (!CheckCollaboratorType(type)) {
8739         WLOGFE("collaborator unregister failed, invalid type.");
8740         return WSError::WS_ERROR_INVALID_TYPE;
8741     }
8742     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(type);
8743     if (collaborator != nullptr && collaborator->AsObject() != nullptr) {
8744         TLOGI(WmsLogTag::DEFAULT, "Remove collaborator death recipient");
8745         collaborator->AsObject()->RemoveDeathRecipient(collaboratorDeathRecipient_);
8746     }
8747     {
8748         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8749         collaboratorMap_.erase(type);
8750     }
8751     return WSError::WS_OK;
8752 }
8753 
ClearAllCollaboratorSessions()8754 void SceneSessionManager::ClearAllCollaboratorSessions()
8755 {
8756     TLOGI(WmsLogTag::DEFAULT, "run");
8757     std::vector<sptr<SceneSession>> collaboratorSessions;
8758     {
8759         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8760         for (const auto& [_, sceneSession] : sceneSessionMap_) {
8761             if (sceneSession != nullptr && CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
8762                 collaboratorSessions.push_back(sceneSession);
8763             }
8764         }
8765     }
8766     for (const auto& sceneSession : collaboratorSessions) {
8767         sceneSession->Clear();
8768     }
8769 }
8770 
CheckCollaboratorType(int32_t type)8771 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
8772 {
8773     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
8774         WLOGFD("type is invalid");
8775         return false;
8776     }
8777     return true;
8778 }
8779 
CheckIfReuseSession(SessionInfo& sessionInfo)8780 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
8781 {
8782     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
8783         sessionInfo.moduleName_);
8784     if (abilityInfo == nullptr) {
8785         WLOGFE("abilityInfo is nullptr!");
8786         return BrokerStates::BROKER_UNKOWN;
8787     }
8788     sessionInfo.abilityInfo = abilityInfo;
8789     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
8790     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
8791         collaboratorType = CollaboratorType::RESERVE_TYPE;
8792     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
8793         collaboratorType = CollaboratorType::OTHERS_TYPE;
8794     }
8795     if (!CheckCollaboratorType(collaboratorType)) {
8796         WLOGFW("checked not collaborator!");
8797         return BrokerStates::BROKER_UNKOWN;
8798     }
8799     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
8800     sessionInfo.collaboratorType_ = collaboratorType;
8801     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8802     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
8803         WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
8804         sessionInfo.reuse = true;
8805     } else {
8806         sessionInfo.reuse = false;
8807     }
8808     WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
8809         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
8810     return resultValue;
8811 }
8812 
NotifyStartAbility( int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)8813 BrokerStates SceneSessionManager::NotifyStartAbility(
8814     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
8815 {
8816     WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
8817     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8818     if (collaborator == nullptr) {
8819         return BrokerStates::BROKER_UNKOWN;
8820     }
8821     if (sessionInfo.want == nullptr) {
8822         WLOGFI("sessionInfo.want is nullptr, init");
8823         sessionInfo.want = std::make_shared<AAFwk::Want>();
8824         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
8825             sessionInfo.moduleName_);
8826     }
8827     auto accessTokenIDEx = sessionInfo.callingTokenId_;
8828     if (collaborator != nullptr) {
8829         containerStartAbilityTime = std::chrono::duration_cast<std::chrono::milliseconds>(
8830             std::chrono::system_clock::now().time_since_epoch()).count();
8831 
8832         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8833         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
8834             WLOGFI("want affinity exit %{public}s.", affinity.c_str());
8835             return BrokerStates::BROKER_UNKOWN;
8836         }
8837         sessionInfo.want->SetParam("oh_persistentId", persistentId);
8838         int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
8839             currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
8840         WLOGFI("collaborator ret: %{public}d", ret);
8841         if (ret == 0) {
8842             return BrokerStates::BROKER_STARTED;
8843         } else {
8844             return BrokerStates::BROKER_NOT_START;
8845         }
8846     }
8847     return BrokerStates::BROKER_UNKOWN;
8848 }
8849 
NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)8850 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
8851 {
8852     if (sceneSession == nullptr) {
8853         WLOGFE("sceneSession is nullptr");
8854         return;
8855     }
8856     if (sessionInfo.want == nullptr) {
8857         WLOGFI("sessionInfo.want is nullptr");
8858         return;
8859     }
8860     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8861     if (collaborator == nullptr) {
8862         return;
8863     }
8864     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8865     if (abilitySessionInfo == nullptr) {
8866         WLOGFE("abilitySessionInfo is nullptr");
8867         return;
8868     }
8869     abilitySessionInfo->want = *(sessionInfo.want);
8870     if (collaborator != nullptr) {
8871         int32_t missionId = abilitySessionInfo->persistentId;
8872         std::string bundleName = sessionInfo.bundleName_;
8873         int64_t timestamp = containerStartAbilityTime;
8874         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
8875         WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
8876             missionId, bundleName.c_str());
8877         collaborator->NotifyMissionCreated(abilitySessionInfo);
8878     }
8879 }
8880 
NotifyLoadAbility(int32_t collaboratorType, sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)8881 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
8882     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
8883 {
8884     WLOGFD("type: %{public}d", collaboratorType);
8885     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8886     if (collaborator != nullptr) {
8887         WLOGFI("called NotifyLoadAbility");
8888         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
8889     }
8890 }
8891 
8892 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)8893 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
8894 {
8895     WLOGFD("Enter");
8896     if (sceneSession == nullptr) {
8897         WLOGFE("sceneSession is nullptr");
8898         return;
8899     }
8900     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8901     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8902     if (collaborator != nullptr) {
8903         WLOGFI("called UpdateMissionInfo");
8904         collaborator->UpdateMissionInfo(abilitySessionInfo);
8905     }
8906 }
8907 
NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)8908 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
8909 {
8910     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8911     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8912     if (collaborator != nullptr) {
8913         WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
8914         collaborator->NotifyMoveMissionToForeground(persistentId);
8915     }
8916 }
8917 
NotifyClearSession(int32_t collaboratorType, int32_t persistentId)8918 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
8919 {
8920     WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8921     sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8922     if (collaborator != nullptr) {
8923         WLOGFI("called NotifyClearMission %{public}d", persistentId);
8924         collaborator->NotifyClearMission(persistentId);
8925     }
8926 }
8927 
PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)8928 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
8929 {
8930     if (sceneSession == nullptr) {
8931         TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
8932         return false;
8933     }
8934     std::string sessionAffinity;
8935     TLOGI(WmsLogTag::WMS_LIFE, "call");
8936     if (sceneSession->GetSessionInfo().want != nullptr) {
8937         sessionAffinity = sceneSession->GetSessionInfo().want
8938             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8939     }
8940     if (sessionAffinity.empty()) {
8941         TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
8942         BrokerStates notifyReturn = NotifyStartAbility(
8943             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
8944         if (notifyReturn != BrokerStates::BROKER_STARTED) {
8945             TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
8946             return false;
8947         }
8948     }
8949     if (sceneSession->GetSessionInfo().want != nullptr) {
8950         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
8951             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
8952         TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
8953             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
8954             sceneSession->GetSessionInfo().sessionAffinity.c_str());
8955     } else {
8956         TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
8957     }
8958     return true;
8959 }
8960 
PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)8961 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
8962 {
8963     if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
8964         return false;
8965     }
8966     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
8967     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
8968     return true;
8969 }
8970 
AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)8971 void SceneSessionManager::AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)
8972 {
8973     TLOGI(WmsLogTag::WMS_LAYOUT, "displayId: %{public}" PRIu64 ", "
8974         "type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
8975         "height: %{public}d", displayId, type, area.posX_, area.posY_, area.width_, area.height_);
8976     SceneSession::AddOrUpdateWindowDragHotArea(displayId, type, area);
8977 }
8978 
UpdateMaximizeMode(int32_t persistentId, bool isMaximize)8979 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
8980 {
8981     auto task = [this, persistentId, isMaximize]() -> WSError {
8982         WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
8983         auto sceneSession = GetSceneSession(persistentId);
8984         if (sceneSession == nullptr) {
8985             WLOGFE("could not find window, persistentId:%{public}d", persistentId);
8986             return WSError::WS_ERROR_INVALID_WINDOW;
8987         }
8988         sceneSession->UpdateMaximizeMode(isMaximize);
8989         return WSError::WS_OK;
8990     };
8991     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
8992     return WSError::WS_OK;
8993 }
8994 
GetIsLayoutFullScreen(bool& isLayoutFullScreen)8995 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
8996 {
8997     auto task = [this, &isLayoutFullScreen]() {
8998         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8999         for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9000             auto sceneSession = item->second;
9001             if (sceneSession == nullptr) {
9002                 WLOGFE("Session is nullptr");
9003                 continue;
9004             }
9005             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9006                 continue;
9007             }
9008             auto state = sceneSession->GetSessionState();
9009             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9010                 continue;
9011             }
9012             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9013                 continue;
9014             }
9015             auto property = sceneSession->GetSessionProperty();
9016             if (property == nullptr) {
9017                 WLOGFE("Property is nullptr");
9018                 continue;
9019             }
9020             isLayoutFullScreen = property->IsLayoutFullScreen();
9021             auto persistentId = sceneSession->GetPersistentId();
9022             if (isLayoutFullScreen) {
9023                 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
9024                 return WSError::WS_OK;
9025             } else {
9026                 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
9027             }
9028         }
9029         WLOGFD("No immersive window");
9030         return WSError::WS_OK;
9031     };
9032 
9033     taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
9034     return WSError::WS_OK;
9035 }
9036 
UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)9037 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
9038 {
9039     auto scnSession = GetSceneSession(persistentId);
9040     if (!scnSession) {
9041         WLOGFE("session is nullptr");
9042         return WSError::WS_ERROR_INVALID_WINDOW;
9043     }
9044     auto fromScreenId = scnSession->GetSessionInfo().screenId_;
9045     scnSession->SetScreenId(screenId);
9046     auto sessionProperty = scnSession->GetSessionProperty();
9047     if (!sessionProperty) {
9048         WLOGFE("Property is null, synchronous screenId failed");
9049         return WSError::WS_ERROR_NULLPTR;
9050     }
9051     sessionProperty->SetDisplayId(screenId);
9052     WLOGFD("Session move display %{public}" PRIu64 " from %{public}" PRIu64, screenId, fromScreenId);
9053     NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
9054     scnSession->NotifyDisplayMove(fromScreenId, screenId);
9055     scnSession->UpdateDensity();
9056     return WSError::WS_OK;
9057 }
9058 
NotifyStackEmpty(int32_t persistentId)9059 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
9060 {
9061     TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
9062     auto task = [this, persistentId]() {
9063         auto scnSession = GetSceneSession(persistentId);
9064         if (!scnSession) {
9065             TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
9066             return WSError::WS_ERROR_INVALID_WINDOW;
9067         }
9068         NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
9069         return WSError::WS_OK;
9070     };
9071     taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
9072     return WSError::WS_OK;
9073 }
9074 
OnImmersiveStateChange(ScreenId screenId, bool& immersive)9075 void DisplayChangeListener::OnImmersiveStateChange(ScreenId screenId, bool& immersive)
9076 {
9077     immersive = SceneSessionManager::GetInstance().GetImmersiveState(screenId);
9078 }
9079 
GetImmersiveState(ScreenId screenId)9080 bool SceneSessionManager::GetImmersiveState(ScreenId screenId)
9081 {
9082     auto task = [this, screenId] {
9083         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9084         for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9085             auto sceneSession = item->second;
9086             if (sceneSession == nullptr) {
9087                 WLOGFE("Session is nullptr");
9088                 continue;
9089             }
9090             if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9091                 continue;
9092             }
9093             auto state = sceneSession->GetSessionState();
9094             if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9095                 continue;
9096             }
9097             if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9098                 continue;
9099             }
9100             auto property = sceneSession->GetSessionProperty();
9101             if (property == nullptr) {
9102                 WLOGFE("Property is nullptr");
9103                 continue;
9104             }
9105             if (property->GetDisplayId() != screenId) {
9106                 continue;
9107             }
9108             auto sysBarProperty = property->GetSystemBarProperty();
9109             if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
9110                 WLOGI("GetImmersiveState, window is immersive. id:%{public}d", sceneSession->GetPersistentId());
9111                 return true;
9112             } else {
9113                 WLOGI("GetImmersiveState, statusBar is enabled. id:%{public}d", sceneSession->GetPersistentId());
9114                 break;
9115             }
9116         }
9117         WLOGI("GetImmersiveState, not immersive");
9118         return false;
9119     };
9120     return taskScheduler_->PostSyncTask(task, "GetImmersiveState");
9121 }
9122 
NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason, bool withAnimation)9123 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
9124     bool withAnimation)
9125 {
9126     session->NotifySessionForeground(reason, withAnimation);
9127 }
9128 
NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason, bool withAnimation, bool isFromInnerkits)9129 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
9130     bool withAnimation, bool isFromInnerkits)
9131 {
9132     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
9133 }
9134 
UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)9135 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
9136 {
9137     auto sceneSession = GetSceneSession(persistentId);
9138     if (sceneSession == nullptr) {
9139         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9140         return WSError::WS_ERROR_INVALID_WINDOW;
9141     }
9142     return sceneSession->UpdateTitleInTargetPos(isShow, height);
9143 }
9144 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)9145 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9146 {
9147     WLOGFI("AppAnrListener OnAppDebugStarted");
9148     if (debugInfos.empty()) {
9149         WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9150         return;
9151     }
9152 }
9153 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)9154 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9155 {
9156     WLOGFI("AppAnrListener OnAppDebugStoped");
9157     if (debugInfos.empty()) {
9158         WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9159         return;
9160     }
9161 }
9162 
FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)9163 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9164 {
9165     if (!Session::IsScbCoreEnabled()) {
9166         return;
9167     }
9168     auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9169         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9170         TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9171         {
9172             std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9173             nextFlushCompletedCV_.notify_all();
9174         }
9175         processingFlushUIParams_.store(true);
9176         {
9177             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9178             for (const auto& item : sceneSessionMap_) {
9179                 auto sceneSession = item.second;
9180                 if (sceneSession == nullptr) {
9181                     continue;
9182                 }
9183                 if (sceneSession->GetSessionInfo().screenId_ != screenId) {
9184                     continue;
9185                 }
9186                 auto iter = uiParams.find(sceneSession->GetPersistentId());
9187                 if (iter != uiParams.end()) {
9188                     sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9189                 } else {
9190                     sessionMapDirty_ |= sceneSession->UpdateUIParam();
9191                 }
9192             }
9193         }
9194         processingFlushUIParams_.store(false);
9195 
9196         // post process if dirty
9197         if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9198             static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9199             TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9200             for (const auto& item : uiParams) {
9201                 TLOGD(WmsLogTag::WMS_PIPELINE,
9202                     "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX: %{public}f, transY: %{public}f,"
9203                     " needSync: %{public}d, interactive: %{public}d",
9204                     item.first, item.second.zOrder_, item.second.rect_.ToString().c_str(), item.second.transX_,
9205                     item.second.transY_, item.second.needSync_, item.second.interactive_);
9206             }
9207             ProcessFocusZOrderChange(sessionMapDirty_);
9208             PostProcessFocus();
9209             PostProcessProperty(sessionMapDirty_);
9210             NotifyAllAccessibilityInfo();
9211             AnomalyDetection::SceneZOrderCheckProcess();
9212         } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9213             PostProcessProperty(sessionMapDirty_);
9214         }
9215         FlushWindowInfoToMMI();
9216         sessionMapDirty_ = 0;
9217         {
9218             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9219             for (const auto& item : sceneSessionMap_) {
9220                 auto sceneSession = item.second;
9221                 if (sceneSession == nullptr) {
9222                     continue;
9223                 }
9224                 sceneSession->ResetDirtyFlags();
9225                 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9226                     sceneSession->SetUIStateDirty(false);
9227                 }
9228             }
9229         }
9230     };
9231     taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9232 }
9233 
ProcessFocusZOrderChange(uint32_t dirty)9234 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty) {
9235     if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9236         return;
9237     }
9238     if (!systemConfig_.IsPhoneWindow() && !systemConfig_.IsPadWindow()) {
9239         return;
9240     }
9241     TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9242     auto focusedSession = GetSceneSession(focusedSessionId_);
9243     // only when it's from a high zOrder to a low zOrder
9244     if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9245         focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9246         return;
9247     }
9248     auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9249     if (voiceInteractionSession == nullptr) {
9250         return;
9251     }
9252     TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9253           "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9254           voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9255     if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9256         focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9257         return;
9258     }
9259     RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9260 }
9261 
PostProcessFocus()9262 void SceneSessionManager::PostProcessFocus()
9263 {
9264     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9265     // priority process focus requests from top to bottom
9266     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9267     {
9268         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9269         for (auto& iter : sceneSessionMap_) {
9270             auto session = iter.second;
9271             if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9272                 continue;
9273             }
9274             processingSessions.push_back(iter);
9275         }
9276     }
9277     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
9278         bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
9279             !rhs.second->GetPostProcessFocusState().isFocused_;
9280         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
9281         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
9282         return focusCmp || lhsZOrder > rhsZOrder;
9283     };
9284     std::sort(processingSessions.begin(), processingSessions.end(), cmp);
9285 
9286     // only change focus one time
9287     bool focusChanged = false;
9288     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9289         auto session = iter->second;
9290         if (session == nullptr) {
9291             WLOGFE("session is nullptr");
9292             continue;
9293         }
9294         TLOGD(WmsLogTag::WMS_PIPELINE,
9295             "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
9296             session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
9297             session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
9298         if (!session->IsFocusableOnShow() &&
9299             (session->GetPostProcessFocusState().reason_ == FocusChangeReason::FOREGROUND ||
9300              session->GetPostProcessFocusState().reason_ == FocusChangeReason::APP_FOREGROUND)) {
9301             TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus", session->GetPersistentId());
9302             session->ResetPostProcessFocusState();
9303             session->SetFocusableOnShow(true);
9304             continue;
9305         }
9306         if (focusChanged) {
9307             session->ResetPostProcessFocusState();
9308             continue;
9309         }
9310         WSError ret = WSError::WS_DO_NOTHING;
9311         if (session->GetPostProcessFocusState().isFocused_) {
9312             if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
9313                 ret = RequestSessionFocusImmediately(session->GetPersistentId());
9314             } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::RECENT) {
9315                 ret = RequestSessionFocus(session->GetPersistentId(),
9316                                           session->GetPostProcessFocusState().byForeground_,
9317                                           session->GetPostProcessFocusState().reason_);
9318             } else {
9319                 ret = RequestSessionFocus(session->GetPersistentId(), true,
9320                                           session->GetPostProcessFocusState().reason_);
9321             }
9322         } else {
9323             ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
9324         }
9325         session->ResetPostProcessFocusState();
9326         // if succeed then end process
9327         if (ret == WSError::WS_OK) {
9328             focusChanged = true;
9329         }
9330     }
9331 }
9332 
PostProcessProperty(uint32_t dirty)9333 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
9334 {
9335     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
9336     if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9337         // only trigger update avoid area
9338         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9339         for (auto& iter : sceneSessionMap_) {
9340             auto session = iter.second;
9341             if (session == nullptr) {
9342                 continue;
9343             }
9344             session->PostProcessNotifyAvoidArea();
9345         }
9346         return;
9347     }
9348 
9349     std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9350     {
9351         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9352         for (auto& iter : sceneSessionMap_) {
9353             auto session = iter.second;
9354             if (session == nullptr || !session->GetPostProcessProperty()) {
9355                 continue;
9356             }
9357             processingSessions.push_back(iter);
9358         }
9359     }
9360 
9361     for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9362         auto session = iter->second;
9363         if (session == nullptr) {
9364             WLOGFE("session is nullptr");
9365             continue;
9366         }
9367         TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
9368         UpdateForceHideState(session, session->GetSessionProperty(), true);
9369         HandleKeepScreenOn(session, session->IsKeepScreenOn());
9370         UpdatePrivateStateAndNotify(session->GetPersistentId());
9371         if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9372             ProcessSubSessionForeground(session);
9373         }
9374         session->SetPostProcessProperty(false);
9375     }
9376 
9377     // update avoid area
9378     {
9379         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9380         for (auto& iter : sceneSessionMap_) {
9381             auto session = iter.second;
9382             if (session == nullptr) {
9383                 continue;
9384             }
9385             session->PostProcessNotifyAvoidArea();
9386         }
9387     }
9388 }
9389 
9390 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)9391 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
9392 {
9393     WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
9394     auto isSaCall = SessionPermission::IsSACalling();
9395     if (!isSaCall) {
9396         WLOGFE("The interface only support for sa call");
9397         return WSError::WS_ERROR_INVALID_PERMISSION;
9398     }
9399     auto task = [this, persistentId]() {
9400         auto sceneSession = GetSceneSession(persistentId);
9401         if (sceneSession == nullptr) {
9402             WLOGFE("session is nullptr");
9403             return WSError::WS_ERROR_INVALID_SESSION;
9404         }
9405         if (!IsSessionVisibleForeground(sceneSession)) {
9406             WLOGFD("session is not visible!");
9407             return WSError::WS_DO_NOTHING;
9408         }
9409         FocusChangeReason reason = FocusChangeReason::MOVE_UP;
9410         RequestSessionFocus(persistentId, true, reason);
9411         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
9412             sceneSession->RaiseToAppTop();
9413         }
9414         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
9415             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
9416             WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
9417             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9418         }
9419         if (sceneSession == nullptr) {
9420             WLOGFE("parent session is nullptr");
9421             return WSError::WS_ERROR_INVALID_SESSION;
9422         }
9423         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9424             sceneSession->NotifyClick();
9425             return WSError::WS_OK;
9426         } else {
9427             WLOGFE("session is not app main window!");
9428             return WSError::WS_ERROR_INVALID_SESSION;
9429         }
9430     };
9431     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
9432     return WSError::WS_OK;
9433 }
9434 
ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)9435 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
9436 {
9437     WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
9438     if (sourcePersistentId != focusedSessionId_) {
9439         WLOGFE("source session need be focused");
9440         return WSError::WS_ERROR_INVALID_OPERATION;
9441     }
9442     if (targetPersistentId == focusedSessionId_) {
9443         WLOGFE("target session has been focused");
9444         return WSError::WS_DO_NOTHING;
9445     }
9446     sptr<SceneSession> sourceSession = nullptr;
9447     WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
9448     if (ret != WSError::WS_OK) {
9449         return ret;
9450     }
9451     sptr<SceneSession> targetSession = nullptr;
9452     ret = GetAppMainSceneSession(targetSession, targetPersistentId);
9453     if (ret != WSError::WS_OK) {
9454         return ret;
9455     }
9456     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
9457         WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
9458             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
9459         return WSError::WS_ERROR_INVALID_CALLING;
9460     }
9461     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
9462         return WSError::WS_ERROR_INVALID_CALLING;
9463     }
9464     int32_t callingPid = IPCSkeleton::GetCallingPid();
9465     if (callingPid != targetSession->GetCallingPid()) {
9466         TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
9467         return WSError::WS_ERROR_INVALID_CALLING;
9468     }
9469     targetSession->NotifyClick();
9470     FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
9471     return RequestSessionFocus(targetPersistentId, false, reason);
9472 }
9473 
GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)9474 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
9475 {
9476     sceneSession = GetSceneSession(persistentId);
9477     if (sceneSession == nullptr) {
9478         WLOGFE("session(%{public}d) is nullptr", persistentId);
9479         return WSError::WS_ERROR_INVALID_SESSION;
9480     }
9481     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9482         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
9483             WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
9484             return WSError::WS_ERROR_INVALID_CALLING;
9485         }
9486         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9487         if (sceneSession == nullptr) {
9488             WLOGFE("session(%{public}d) parent is nullptr", persistentId);
9489             return WSError::WS_ERROR_INVALID_SESSION;
9490         }
9491     }
9492     return WSError::WS_OK;
9493 }
9494 
GetSessionSnapshotPixelMap(const int32_t persistentId, const float scaleParam)9495 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
9496     const float scaleParam)
9497 {
9498     auto sceneSession = GetSceneSession(persistentId);
9499     if (!sceneSession) {
9500         WLOGFE("get scene session is nullptr");
9501         return nullptr;
9502     }
9503 
9504     wptr<SceneSession> weakSceneSession(sceneSession);
9505     auto task = [this, persistentId, scaleParam, weakSceneSession]() {
9506         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
9507         auto scnSession = weakSceneSession.promote();
9508         std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
9509         if (scnSession == nullptr) {
9510             WLOGFE("session is nullptr");
9511             return pixelMap;
9512         }
9513 
9514         bool isPc = systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode();
9515         pixelMap = scnSession->Snapshot(false, scaleParam, isPc);
9516         if (!pixelMap) {
9517             WLOGFI("get local snapshot pixelmap start");
9518             pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
9519         }
9520         return pixelMap;
9521     };
9522     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
9523 }
9524 
GetSceneSessionMap()9525 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
9526 {
9527     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
9528     {
9529         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9530         retSceneSessionMap = sceneSessionMap_;
9531     }
9532     EraseIf(retSceneSessionMap, [this](const auto& pair) {
9533         if (pair.second == nullptr) {
9534             return true;
9535         }
9536 
9537         if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
9538             if (pair.second->IsVisible()) {
9539                 return false;
9540             }
9541             return true;
9542         }
9543 
9544         if (pair.second->IsSystemInput()) {
9545             return false;
9546         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
9547             return false;
9548         }
9549 
9550         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
9551             return true;
9552         }
9553         return false;
9554     });
9555     return retSceneSessionMap;
9556 }
9557 
NotifyUpdateRectAfterLayout()9558 void SceneSessionManager::NotifyUpdateRectAfterLayout()
9559 {
9560     auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
9561     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
9562     if (transactionController) {
9563         rsTransaction = transactionController->GetRSTransaction();
9564     }
9565     auto task = [this, rsTransaction]() {
9566         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9567         for (const auto& iter: sceneSessionMap_) {
9568             auto sceneSession = iter.second;
9569             if (sceneSession && sceneSession->IsDirtyWindow()) {
9570                 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
9571             }
9572         }
9573     };
9574     // need sync task since animation transcation need
9575     return taskScheduler_->PostAsyncTask(task, "NotifyUpdateRectAfterLayout");
9576 }
9577 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)9578 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
9579 {
9580     if (!SessionPermission::IsSystemCalling()) {
9581         WLOGFE("GetVisibilityWindowInfo permission denied!");
9582         return WMError::WM_ERROR_NOT_SYSTEM_APP;
9583     }
9584     auto task = [this, &infos]() {
9585         for (auto [surfaceId, _] : lastVisibleData_) {
9586             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9587             if (session == nullptr) {
9588                 continue;
9589             }
9590             WSRect hostRect = session->GetSessionRect();
9591             Rect rect = {hostRect.posX_, hostRect.posY_,
9592                          static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
9593             auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
9594                                                 session->GetSessionProperty());
9595             infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
9596                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
9597                 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_));
9598         }
9599         return WMError::WM_OK;
9600     };
9601     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
9602 }
9603 
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)9604 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
9605 {
9606     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9607     for (const auto& [id, session] : sceneSessionMap_) {
9608         if (session == nullptr) {
9609             continue;
9610         }
9611         uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
9612         windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
9613     }
9614 }
9615 
FlushWindowInfoToMMI(const bool forceFlush)9616 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
9617 {
9618     auto task = [this, forceFlush] {
9619         if (isUserBackground_) {
9620             TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
9621             return;
9622         }
9623         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
9624         SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
9625     };
9626     taskScheduler_->PostAsyncTask(task);
9627 }
9628 
PostFlushWindowInfoTask(FlushWindowInfoTask &&task, const std::string taskName, const int delayTime)9629 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
9630     const std::string taskName, const int delayTime)
9631 {
9632     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
9633 }
9634 
GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId, int32_t& parentId)9635 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
9636     int32_t& parentId)
9637 {
9638     // This function should be called in task
9639     auto iter = extSessionInfoMap_.find(token);
9640     if (iter == extSessionInfoMap_.end()) {
9641         return false;
9642     }
9643     persistentId = iter->second.persistentId;
9644     parentId = iter->second.parentId;
9645     return true;
9646 }
9647 
DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)9648 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)
9649 {
9650     auto task = [this, remoteExtSession]() {
9651         auto iter = remoteExtSessionMap_.find(remoteExtSession);
9652         if (iter == remoteExtSessionMap_.end()) {
9653             TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
9654             return;
9655         }
9656         int32_t persistentId = INVALID_SESSION_ID;
9657         int32_t parentId = INVALID_SESSION_ID;
9658         if (!GetExtensionWindowIds(iter->second, persistentId, parentId)) {
9659             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9660             return;
9661         }
9662 
9663         TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
9664             persistentId, parentId);
9665         auto sceneSession = GetSceneSession(parentId);
9666         if (sceneSession != nullptr) {
9667             auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
9668             sceneSession->RemoveExtWindowFlags(persistentId);
9669             if (oldFlags.hideNonSecureWindowsFlag) {
9670                 HandleSecureSessionShouldHide(sceneSession);
9671             }
9672             if (oldFlags.waterMarkFlag) {
9673                 CheckAndNotifyWaterMarkChangedResult();
9674             }
9675             if (oldFlags.privacyModeFlag) {
9676                 UpdatePrivateStateAndNotify(parentId);
9677             }
9678             sceneSession->RemoveModalUIExtension(persistentId);
9679             sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
9680         } else {
9681             ExtensionWindowFlags actions;
9682             actions.SetAllActive();
9683             HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
9684         }
9685         extSessionInfoMap_.erase(iter->second);
9686         remoteExtSessionMap_.erase(iter);
9687     };
9688     taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
9689 }
9690 
UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)9691 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
9692 {
9693     auto pid = IPCSkeleton::GetCallingRealPid();
9694     auto task = [this, token, pid, rect]() {
9695         int32_t persistentId = INVALID_SESSION_ID;
9696         int32_t parentId = INVALID_SESSION_ID;
9697         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9698             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9699             return;
9700         }
9701         TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
9702             "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
9703             pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
9704         auto parentSession = GetSceneSession(parentId);
9705         if (parentSession) {
9706             auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
9707             auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
9708             Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
9709             ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect };
9710             TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
9711                 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
9712                 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
9713                 parentSession->GetSessionGlobalRect().ToString().c_str());
9714             parentSession->UpdateModalUIExtension(extensionInfo);
9715         }
9716     };
9717     taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
9718 }
9719 
ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)9720 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
9721 {
9722     auto pid = IPCSkeleton::GetCallingRealPid();
9723     auto task = [this, token, pid, posX, posY]() {
9724         int32_t persistentId = INVALID_SESSION_ID;
9725         int32_t parentId = INVALID_SESSION_ID;
9726         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9727             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9728             return;
9729         }
9730         TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
9731             "parentId=%{public}d", pid, persistentId, parentId);
9732         auto parentSession = GetSceneSession(parentId);
9733         if (parentSession && parentSession->HasModalUIExtension()) {
9734             auto modalUIExtension = parentSession->GetLastModalUIExtensionEventInfo();
9735             if ((modalUIExtension.pid == pid) && (modalUIExtension.persistentId == persistentId)) {
9736                 parentSession->ProcessPointDownSession(posX, posY);
9737             }
9738         }
9739     };
9740     taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
9741 }
9742 
AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage, const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)9743 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
9744     const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)
9745 {
9746     auto pid = IPCSkeleton::GetCallingRealPid();
9747     auto task = [this, sessionStage, token, surfaceNodeId, pid]() {
9748         if (sessionStage == nullptr || token == nullptr) {
9749             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9750             return;
9751         }
9752         auto remoteExtSession = sessionStage->AsObject();
9753         if (remoteExtSession == nullptr) {
9754             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9755             return;
9756         }
9757         if (extensionDeath_ == nullptr) {
9758             TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
9759             return;
9760         }
9761         if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
9762             TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
9763             return;
9764         }
9765 
9766         AAFwk::UIExtensionSessionInfo info;
9767         AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
9768         if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
9769             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
9770             return;
9771         }
9772 
9773         int32_t persistentId = info.persistentId;
9774         int32_t parentId = static_cast<int32_t>(info.hostWindowId);
9775         UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
9776         TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
9777             "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
9778             surfaceNodeId, pid);
9779 
9780         remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
9781         extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
9782 
9783         auto parentSession = GetSceneSession(parentId);
9784         if (parentSession) {
9785             parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
9786         }
9787         if (usage == UIExtensionUsage::MODAL && parentSession) {
9788             ExtensionWindowEventInfo extensionInfo {
9789                 .persistentId = persistentId,
9790                 .pid = pid,
9791             };
9792             parentSession->AddModalUIExtension(extensionInfo);
9793         }
9794     };
9795     taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
9796 }
9797 
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage, const sptr<IRemoteObject>& token)9798 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
9799     const sptr<IRemoteObject>& token)
9800 {
9801     TLOGI(WmsLogTag::WMS_UIEXT, "called");
9802     auto task = [this, sessionStage, token]() {
9803         if (sessionStage == nullptr || token == nullptr) {
9804             TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9805             return;
9806         }
9807         auto remoteExtSession = sessionStage->AsObject();
9808         if (remoteExtSession == nullptr) {
9809             TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9810             return;
9811         }
9812         auto iter = remoteExtSessionMap_.find(remoteExtSession);
9813         if (iter->second != token) {
9814             TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
9815             return;
9816         }
9817 
9818         DestroyExtensionSession(remoteExtSession);
9819     };
9820     taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
9821 }
9822 
CalculateCombinedExtWindowFlags()9823 void SceneSessionManager::CalculateCombinedExtWindowFlags()
9824 {
9825     // Only correct when each flag is true when active, and once a uiextension is active, the host is active
9826     combinedExtWindowFlags_.bitData = 0;
9827     for (const auto& iter: extWindowFlagsMap_) {
9828         combinedExtWindowFlags_.bitData |= iter.second.bitData;
9829     }
9830     specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
9831 }
9832 
UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags, ExtensionWindowFlags actions)9833 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
9834     ExtensionWindowFlags actions)
9835 {
9836     auto iter = extWindowFlagsMap_.find(persistentId);
9837     // Each flag is false when inactive, 0 means all flags are inactive
9838     auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
9839     ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
9840     if (newFlags.bitData == 0) {
9841         extWindowFlagsMap_.erase(persistentId);
9842     } else {
9843         extWindowFlagsMap_[persistentId] = newFlags;
9844     }
9845     CalculateCombinedExtWindowFlags();
9846 }
9847 
HideNonSecureFloatingWindows()9848 void SceneSessionManager::HideNonSecureFloatingWindows()
9849 {
9850     bool shouldHide = false;
9851     {
9852         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9853         for (const auto& iter: sceneSessionMap_) {
9854             auto& session = iter.second;
9855             if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
9856                 shouldHide = true;
9857                 break;
9858             }
9859         }
9860     }
9861     if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
9862         TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
9863         shouldHide = true;
9864     }
9865     if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
9866         return;
9867     }
9868 
9869     shouldHideNonSecureFloatingWindows_.store(shouldHide);
9870     for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
9871         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
9872             session->NotifyForceHideChange(shouldHide);
9873             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9874                 session->GetWindowName().c_str(), persistentId, shouldHide);
9875         }
9876     }
9877 }
9878 
HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)9879 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
9880 {
9881     // don't let sub-window show when switching secure host window to background
9882     if (!sceneSession->IsSessionForeground()) {
9883         return;
9884     }
9885 
9886     auto parentId = sceneSession->GetPersistentId();
9887     bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
9888     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9889     for (const auto& [persistentId, session] : sceneSessionMap_) {
9890         if (!session) {
9891             continue;
9892         }
9893         auto property = session->GetSessionProperty();
9894         if (!property || property->GetParentPersistentId() != parentId) {
9895             continue;
9896         }
9897 
9898         if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
9899             session->NotifyForceHideChange(shouldHide);
9900             TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9901                 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
9902         }
9903     }
9904 }
9905 
HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)9906 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
9907 {
9908     if (sceneSession == nullptr) {
9909         TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
9910         return WSError::WS_ERROR_INVALID_SESSION;
9911     }
9912 
9913     HideNonSecureFloatingWindows();
9914     HideNonSecureSubWindows(sceneSession);
9915     return WSError::WS_OK;
9916 }
9917 
HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags, ExtensionWindowFlags actions)9918 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
9919     ExtensionWindowFlags actions)
9920 {
9921     UpdateSpecialExtWindowFlags(persistentId, flags, actions);
9922     if (actions.waterMarkFlag) {
9923         CheckAndNotifyWaterMarkChangedResult();
9924     }
9925     if (actions.hideNonSecureWindowsFlag) {
9926         HideNonSecureFloatingWindows();
9927     }
9928     if (actions.privacyModeFlag) {
9929         UpdatePrivateStateAndNotifyForAllScreens();
9930     }
9931 }
9932 
AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)9933 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
9934 {
9935     TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
9936     if (!SessionPermission::IsSystemCalling()) {
9937         TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
9938         return WSError::WS_ERROR_NOT_SYSTEM_APP;
9939     }
9940     const auto callingPid = IPCSkeleton::GetCallingRealPid();
9941     auto task = [this, persistentId, shouldHide, callingPid]() {
9942         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9943         auto iter = sceneSessionMap_.find(persistentId);
9944         if (iter == sceneSessionMap_.end()) {
9945             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
9946                 persistentId);
9947             return WSError::WS_ERROR_INVALID_SESSION;
9948         }
9949         auto sceneSession = iter->second;
9950         if (sceneSession == nullptr) {
9951             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
9952             return WSError::WS_ERROR_NULLPTR;
9953         }
9954         if (callingPid != sceneSession->GetCallingPid()) {
9955             TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
9956             return WSError::WS_ERROR_INVALID_PERMISSION;
9957         }
9958         sceneSession->SetShouldHideNonSecureWindows(shouldHide);
9959         return HandleSecureSessionShouldHide(sceneSession);
9960     };
9961 
9962     taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
9963     return WSError::WS_OK;
9964 }
9965 
CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const9966 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
9967 {
9968     auto ret = WSError::WS_OK;
9969     bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
9970     if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
9971         actions.hideNonSecureWindowsFlag = false;
9972         actions.waterMarkFlag = false;
9973         TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
9974         ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
9975     }
9976     auto needPrivacyWindow = actions.privacyModeFlag;
9977     if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
9978         actions.privacyModeFlag = false;
9979         TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
9980         ret = WSError::WS_ERROR_INVALID_PERMISSION;
9981     }
9982     return ret;
9983 }
9984 
UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags, uint32_t extWindowActions)9985 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
9986     uint32_t extWindowActions)
9987 {
9988     ExtensionWindowFlags actions(extWindowActions);
9989     auto ret = CheckExtWindowFlagsPermission(actions);
9990     if (actions.bitData == 0) {
9991         return ret;
9992     }
9993 
9994     ExtensionWindowFlags flags(extWindowFlags);
9995     auto task = [this, token, flags, actions]() {
9996         int32_t persistentId = INVALID_SESSION_ID;
9997         int32_t parentId = INVALID_SESSION_ID;
9998         if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9999             TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10000             return WSError::WS_ERROR_INVALID_OPERATION;
10001         }
10002 
10003         TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
10004             "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
10005         auto sceneSession = GetSceneSession(parentId);
10006         if (sceneSession == nullptr) {
10007             TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
10008                 parentId);
10009             HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
10010             return WSError::WS_OK;
10011         }
10012 
10013         auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10014         sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
10015         auto newFlags = sceneSession->GetCombinedExtWindowFlags();
10016         if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
10017             HandleSecureSessionShouldHide(sceneSession);
10018         }
10019         if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
10020             CheckAndNotifyWaterMarkChangedResult();
10021         }
10022         if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
10023             UpdatePrivateStateAndNotify(parentId);
10024         }
10025         return WSError::WS_OK;
10026     };
10027 
10028     taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
10029     return ret;
10030 }
10031 
ReportWindowProfileInfos()10032 void SceneSessionManager::ReportWindowProfileInfos()
10033 {
10034     enum class WindowVisibleState : int32_t {
10035         FOCUSBLE = 0,
10036         VISIBLE,
10037         MINIMIZED,
10038         OCCLUSION
10039     };
10040     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10041     {
10042         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10043         sceneSessionMapCopy = sceneSessionMap_;
10044     }
10045     auto focusWindowId = GetFocusedSessionId();
10046     for (const auto& elem : sceneSessionMapCopy) {
10047         auto curSession = elem.second;
10048         if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10049             curSession->GetWindowType() !=  WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10050             continue;
10051         }
10052         WindowProfileInfo windowProfileInfo;
10053         windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10054         windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10055             curSession->GetSessionProperty()->GetDisplayId());
10056         windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10057         if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10058             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10059         } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10060             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10061         } else if (!curSession->GetRSVisible()) {
10062             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10063         } else {
10064             windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10065         }
10066         WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10067         WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10068             "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10069             windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10070             windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10071     }
10072 }
10073 
IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo, const std::vector<VisibleWindowNumInfo>& currentInfo)10074 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
10075     const std::vector<VisibleWindowNumInfo>& currentInfo)
10076 {
10077     if (lastInfo.size() != currentInfo.size()) {
10078         WLOGFE("last and current info is not Same");
10079         return false;
10080     }
10081     size_t sizeOfLastInfo = lastInfo.size();
10082     for (size_t i = 0; i < sizeOfLastInfo; i++) {
10083         if (lastInfo[i].displayId != currentInfo[i].displayId ||
10084             lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
10085             WLOGFE("last and current visible window num is not Same");
10086             return false;
10087         }
10088     }
10089     return true;
10090 }
10091 
GetDisplayIdByPersistentId(int32_t persistentId, int32_t& displayId)10092 WMError SceneSessionManager::GetDisplayIdByPersistentId(int32_t persistentId, int32_t& displayId)
10093 {
10094     auto task = [this, persistentId, &displayId]() {
10095         sptr<SceneSession> session = GetSceneSession(persistentId);
10096         if (session == nullptr) {
10097             TLOGE(WmsLogTag::WMS_MAIN, "GetDisplayIdByPersistentId: session is nullptr");
10098             return WMError::WM_ERROR_INVALID_SESSION;
10099         }
10100         sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
10101         if (sessionProperty == nullptr) {
10102             TLOGE(WmsLogTag::WMS_MAIN, "GetDisplayIdByPersistentId: sessionProperty is nullptr");
10103             return WMError::WM_ERROR_INVALID_SESSION;
10104         }
10105         displayId = static_cast<int32_t>(sessionProperty->GetDisplayId());
10106         return WMError::WM_OK;
10107     };
10108     return taskScheduler_->PostSyncTask(task, "GetDisplayIdByPersistentId");
10109 }
10110 
CacVisibleWindowNum()10111 void SceneSessionManager::CacVisibleWindowNum()
10112 {
10113     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10114     {
10115         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10116         sceneSessionMapCopy = sceneSessionMap_;
10117     }
10118     std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
10119     bool isFullScreen = true;
10120     for (const auto& elem : sceneSessionMapCopy) {
10121         auto curSession = elem.second;
10122         if (curSession == nullptr) {
10123             continue;
10124         }
10125         bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
10126             curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
10127         if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10128             continue;
10129         }
10130 
10131         bool isWindowVisible = curSession->GetRSVisible();
10132         if (isWindowVisible) {
10133             auto windowMode = curSession->GetWindowMode();
10134             if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
10135                 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
10136                 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
10137                 isFullScreen = false;
10138             }
10139             uint32_t displayId = static_cast<uint32_t>(curSession->GetSessionProperty()->GetDisplayId());
10140             auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10141                 [=](const VisibleWindowNumInfo& info) {
10142                     return info.displayId == displayId;
10143             });
10144             if (it == visibleWindowNumInfo.end()) {
10145                 visibleWindowNumInfo.push_back({displayId, 1});
10146             } else {
10147                 it->visibleWindowNum++;
10148             }
10149         }
10150     }
10151     if (isFullScreen) {
10152         std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10153                       [](auto& info) { info.visibleWindowNum = 1; });
10154     }
10155     std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
10156     if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10157         SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10158         lastInfo_ = visibleWindowNumInfo;
10159     }
10160 }
10161 
GetHostWindowRect(int32_t hostWindowId, Rect& rect)10162 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
10163 {
10164     TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
10165     if (!SessionPermission::IsSystemCalling()) {
10166         TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
10167         return WSError::WS_ERROR_NOT_SYSTEM_APP;
10168     }
10169     auto task = [this, hostWindowId, &rect]() {
10170         auto sceneSession = GetSceneSession(hostWindowId);
10171         if (sceneSession == nullptr) {
10172             TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
10173             return WSError::WS_ERROR_INVALID_SESSION;
10174         }
10175         WSRect hostRect = sceneSession->GetSessionRect();
10176         rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
10177         return WSError::WS_OK;
10178     };
10179     taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
10180     return WSError::WS_OK;
10181 }
10182 
GetDisplayRegion(DisplayId displayId)10183 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10184 {
10185     if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10186         return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10187     }
10188     TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10189     auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10190     if (display == nullptr) {
10191         TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10192         return nullptr;
10193     }
10194     auto displayInfo = display->GetDisplayInfo();
10195     if (displayInfo == nullptr) {
10196         TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
10197         return nullptr;
10198     }
10199     int32_t displayWidth = displayInfo->GetWidth();
10200     int32_t displayHeight = displayInfo->GetHeight();
10201     if (displayWidth == 0 || displayHeight == 0) {
10202         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10203         return nullptr;
10204     }
10205 
10206     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10207     auto region = std::make_shared<SkRegion>(rect);
10208     displayRegionMap_[displayId] = region;
10209     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10210     return std::make_shared<SkRegion>(rect);
10211 }
10212 
UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)10213 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
10214 {
10215     if (displayInfo == nullptr) {
10216         TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
10217         return;
10218     }
10219     auto displayId = displayInfo->GetDisplayId();
10220     int32_t displayWidth = displayInfo->GetWidth();
10221     int32_t displayHeight = displayInfo->GetHeight();
10222     if (displayWidth == 0 || displayHeight == 0) {
10223         TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10224         return;
10225     }
10226     SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10227     auto region = std::make_shared<SkRegion>(rect);
10228     displayRegionMap_[displayId] = region;
10229     TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10230 }
10231 
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)10232 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
10233 {
10234     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10235     for (const auto& item : sceneSessionMap_) {
10236         auto sceneSession = item.second;
10237         if (sceneSession == nullptr) {
10238             continue;
10239         }
10240         if (Session::IsScbCoreEnabled()) {
10241             if (!sceneSession->IsVisibleForAccessibility()) {
10242                 continue;
10243             }
10244         } else {
10245             if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
10246                 continue;
10247             }
10248         }
10249         if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10250             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10251             sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10252             continue;
10253         }
10254         sceneSessionList.push_back(sceneSession);
10255     }
10256 }
10257 
FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList, std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)10258 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
10259     std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
10260 {
10261     for (const auto& sceneSession : sceneSessionList) {
10262         if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
10263             TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
10264         }
10265     }
10266 }
10267 
FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)10268 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
10269 {
10270     std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
10271         return a->GetZOrder() > b->GetZOrder();
10272     });
10273     std::vector<sptr<SceneSession>> result;
10274     std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
10275     for (const auto& sceneSession : sceneSessionList) {
10276         if (sceneSession == nullptr) {
10277             TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
10278             continue;
10279         }
10280         auto sessionProperty = sceneSession->GetSessionProperty();
10281         if (sessionProperty == nullptr) {
10282             TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
10283             continue;
10284         }
10285         std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
10286         auto displayId = sessionProperty->GetDisplayId();
10287         if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
10288             unaccountedSpace = unaccountedSpaceMap[displayId];
10289         } else {
10290             unaccountedSpace = GetDisplayRegion(displayId);
10291             if (unaccountedSpace == nullptr) {
10292                 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
10293                 continue;
10294             }
10295             unaccountedSpaceMap[displayId] = unaccountedSpace;
10296         }
10297         WSRect wsRect = sceneSession->GetSessionRect();
10298         SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
10299                               .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
10300         SkRegion windowRegion(windowBounds);
10301         if (unaccountedSpace->quickReject(windowRegion)) {
10302             TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10303                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10304             continue;
10305         }
10306         if (!unaccountedSpace->intersects(windowRegion)) {
10307             TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10308                 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10309             continue;
10310         }
10311         result.push_back(sceneSession);
10312         unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
10313         if (unaccountedSpace->isEmpty()) {
10314             break;
10315         }
10316     }
10317     sceneSessionList = result;
10318 }
10319 
NotifyAllAccessibilityInfo()10320 void SceneSessionManager::NotifyAllAccessibilityInfo()
10321 {
10322     if (isUserBackground_) {
10323         TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
10324         return;
10325     }
10326     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::NotifyAllAccessibilityInfo");
10327     std::vector<sptr<SceneSession>> sceneSessionList;
10328     GetAllSceneSessionForAccessibility(sceneSessionList);
10329     FilterSceneSessionCovered(sceneSessionList);
10330 
10331     std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
10332     FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
10333 
10334     for (const auto& item : accessibilityInfo) {
10335         TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, "
10336             "bundle=%{public}s,bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
10337             item->wid_, item->innerWid_, item->bundleName_.c_str(),
10338             item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
10339         for (const auto& rect : item->touchHotAreas_) {
10340             TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d,"
10341                 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
10342         }
10343     }
10344 
10345     SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
10346         WindowUpdateType::WINDOW_UPDATE_ALL);
10347 }
10348 
RemoveFailRecoveredSession()10349 void SceneSessionManager::RemoveFailRecoveredSession()
10350 {
10351     for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10352         auto sceneSession = GetSceneSession(persistentId);
10353         if (sceneSession == nullptr) {
10354             TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10355             continue;
10356         }
10357         if (!sceneSession->IsRecovered()) {
10358             TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10359             continue;
10360         }
10361         const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10362         if (!scnSessionInfo) {
10363             TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr, persistentId = %{public}d", persistentId);
10364             continue;
10365         }
10366         TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10367         sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10368     }
10369     failRecoveredPersistentIdSet_.clear();
10370 }
10371 
ReclaimPurgeableCleanMem()10372 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
10373 {
10374 #ifdef MEMMGR_WINDOW_ENABLE
10375     return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
10376 #else
10377     return -1;
10378 #endif
10379 }
10380 
GetWindowStatus(WindowMode mode, SessionState sessionState, const sptr<WindowSessionProperty>& property)10381 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
10382     const sptr<WindowSessionProperty>& property)
10383 {
10384     auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
10385     if (property == nullptr) {
10386         return windowStatus;
10387     }
10388     if (mode == WindowMode::WINDOW_MODE_FLOATING) {
10389         windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
10390         if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
10391             windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
10392         }
10393     } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
10394         windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
10395     } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
10396         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10397     } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
10398         windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
10399     }
10400     return windowStatus;
10401 }
10402 
GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)10403 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
10404 {
10405     if (!SessionPermission::IsStartedByInputMethod()) {
10406         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10407         return WMError::WM_ERROR_INVALID_PERMISSION;
10408     }
10409     auto scnSession = GetSceneSession(persistentId);
10410     if (scnSession == nullptr) {
10411         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10412         return WMError::WM_ERROR_NULLPTR;
10413     }
10414 
10415     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10416         persistentId, scnSession->GetWindowType());
10417 
10418     auto sessionProperty = scnSession->GetSessionProperty();
10419     if (sessionProperty == nullptr) {
10420         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10421         return WMError::WM_ERROR_INVALID_WINDOW;
10422     }
10423     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10424     auto callingSession = GetSceneSession(callingWindowId);
10425     if (callingSession == nullptr) {
10426         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10427         callingSession = GetSceneSession(focusedSessionId_);
10428         if (callingSession == nullptr) {
10429             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10430             return WMError::WM_ERROR_INVALID_WINDOW;
10431         }
10432     }
10433     if (callingSession->IsSystemSession()) {
10434         windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10435     } else {
10436         windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
10437             callingSession->GetSessionProperty());
10438     }
10439     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
10440         persistentId, windowStatus);
10441     return WMError::WM_OK;
10442 }
10443 
GetCallingWindowRect(int32_t persistentId, Rect& rect)10444 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
10445 {
10446     if (!SessionPermission::IsStartedByInputMethod()) {
10447         TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10448         return WMError::WM_ERROR_INVALID_PERMISSION;
10449     }
10450     auto scnSession = GetSceneSession(persistentId);
10451     if (scnSession == nullptr) {
10452         TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10453         return WMError::WM_ERROR_NULLPTR;
10454     }
10455     TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10456         persistentId, scnSession->GetWindowType());
10457     auto sessionProperty = scnSession->GetSessionProperty();
10458     if (sessionProperty == nullptr) {
10459         TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10460         return WMError::WM_ERROR_INVALID_WINDOW;
10461     }
10462     uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10463     auto callingSession = GetSceneSession(callingWindowId);
10464     if (callingSession == nullptr) {
10465         TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10466         callingSession = GetSceneSession(focusedSessionId_);
10467         if (callingSession == nullptr) {
10468             TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10469             return WMError::WM_ERROR_INVALID_WINDOW;
10470         }
10471     }
10472     WSRect sessionRect = callingSession->GetSessionRect();
10473     rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
10474     TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
10475         "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10476     return WMError::WM_OK;
10477 }
10478 
GetWindowModeType(WindowModeType& windowModeType)10479 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
10480 {
10481     if (!SessionPermission::IsSACalling()) {
10482         WLOGFE("GetWindowModeType permission denied!");
10483         return WMError::WM_ERROR_INVALID_PERMISSION;
10484     }
10485     windowModeType = CheckWindowModeType();
10486     return WMError::WM_OK;
10487 }
10488 
GetWindowStyleType(WindowStyleType& windowStyleType)10489 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
10490 {
10491     if (!SessionPermission::IsSACalling()) {
10492         TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10493         return WMError::WM_ERROR_INVALID_PERMISSION;
10494     }
10495     if (systemConfig_.IsPcWindow()) {
10496         windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
10497         return WMError::WM_OK;
10498     }
10499     windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
10500         WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
10501     return WMError::WM_OK;
10502 }
10503 
CheckSceneZOrder()10504 void SceneSessionManager::CheckSceneZOrder()
10505 {
10506     auto task = [this]() {
10507         AnomalyDetection::SceneZOrderCheckProcess();
10508     };
10509     taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
10510 }
10511 
GetCustomDecorHeight(int32_t persistentId)10512 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10513 {
10514     int32_t height = 0;
10515     auto sceneSession = GetSceneSession(persistentId);
10516     if (sceneSession == nullptr) {
10517         TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10518         return 0;
10519     }
10520     height = sceneSession->GetCustomDecorHeight();
10521     TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10522     return height;
10523 }
10524 
GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)10525 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
10526 {
10527     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
10528         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
10529         return WMError::WM_ERROR_INVALID_PERMISSION;
10530     }
10531 
10532     if (!topNInfo.empty() || (topNum <= 0)) {
10533         return WMError::WM_ERROR_INVALID_PARAM;
10534     }
10535 
10536     TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
10537     auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
10538         if (session == nullptr) {
10539             return false;
10540         }
10541 
10542         if (topNum == 0) {
10543             return true;
10544         }
10545 
10546         if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
10547             TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
10548             return false;
10549         }
10550 
10551         MainWindowInfo info;
10552         info.pid_ = session->GetCallingPid();
10553         info.bundleName_ = session->GetSessionInfo().bundleName_;
10554         topNInfo.push_back(info);
10555         topNum--;
10556         TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
10557             topNum, info.pid_, info.bundleName_.c_str());
10558         return false;
10559     };
10560     TraverseSessionTree(func, true);
10561 
10562     return WMError::WM_OK;
10563 }
10564 
GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber, int32_t x, int32_t y, std::vector<int32_t>& windowIds)10565 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
10566     int32_t x, int32_t y, std::vector<int32_t>& windowIds)
10567 {
10568     TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
10569           displayId, windowNumber, x, y);
10570     if (displayId == DISPLAY_ID_INVALID) {
10571         TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
10572         return WMError::WM_ERROR_INVALID_PARAM;
10573     }
10574     bool findAllWindow = windowNumber <= 0;
10575     bool checkPoint = (x >= 0 && y >= 0);
10576     std::string callerBundleName = SessionPermission::GetCallingBundleName();
10577     auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
10578         findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
10579         if (session == nullptr) {
10580             return false;
10581         }
10582         auto sessionProperty = session->GetSessionProperty();
10583         if (sessionProperty == nullptr) {
10584             return false;
10585         }
10586         if (!findAllWindow && windowNumber == 0) {
10587             return true;
10588         }
10589         bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
10590         bool isSameDisplayId = sessionProperty->GetDisplayId() == displayId;
10591         bool isRsVisible = session->GetRSVisible();
10592         WSRect windowRect = session->GetSessionRect();
10593         bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
10594         TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
10595                " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
10596                session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
10597                sessionProperty->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
10598         if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
10599             return false;
10600         }
10601         windowIds.emplace_back(session->GetPersistentId());
10602         windowNumber--;
10603         return false;
10604     };
10605     auto task = [this, func = std::move(func)] {
10606         TraverseSessionTree(func, true);
10607         return WMError::WM_OK;
10608     };
10609     return taskScheduler_->PostSyncTask(task, __func__);
10610 }
10611 
NotifyEnterRecentTask(bool enterRecent)10612 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
10613 {
10614     TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
10615     enterRecent_.store(enterRecent);
10616     SetSystemAnimatedScenes(enterRecent ?
10617         SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
10618     auto task = [this] {
10619         for (auto persistentId : gestureBackEnableWindowIdSet_) {
10620             auto sceneSession = GetSceneSession(persistentId);
10621             if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
10622                 continue;
10623             }
10624             UpdateGestureBackEnabled(persistentId);
10625         }
10626     };
10627     taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
10628     return WSError::WS_OK;
10629 }
10630 
GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const10631 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
10632 {
10633     if (!infos.empty()) {
10634         TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
10635         return WMError::WM_ERROR_INVALID_PARAM;
10636     }
10637     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10638         TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
10639         return WMError::WM_ERROR_INVALID_PERMISSION;
10640     }
10641     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10642     for (const auto& iter : sceneSessionMap_) {
10643         auto& session = iter.second;
10644         if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
10645             continue;
10646         }
10647         MainWindowInfo info;
10648         auto abilityInfo = session->GetSessionInfo().abilityInfo;
10649         info.pid_ = session->GetCallingPid();
10650         info.bundleName_ = session->GetSessionInfo().bundleName_;
10651         info.persistentId_ = session->GetPersistentId();
10652         if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
10653             TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
10654             info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
10655             infos.push_back(info);
10656         } else if (abilityInfo != nullptr) {
10657             info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
10658             infos.push_back(info);
10659             TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d,"
10660                 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
10661                 info.bundleName_.c_str(), info.bundleType_);
10662         }
10663     }
10664     return WMError::WM_OK;
10665 }
10666 
ClearMainSessions(const std::vector<int32_t>& persistentIds, std::vector<int32_t>& clearFailedIds)10667 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
10668     std::vector<int32_t>& clearFailedIds)
10669 {
10670     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10671         TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
10672         return WMError::WM_ERROR_INVALID_PERMISSION;
10673     }
10674     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10675         TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10676         return WMError::WM_ERROR_INVALID_PERMISSION;
10677     }
10678     clearFailedIds.clear();
10679     for (const auto persistentId : persistentIds) {
10680         auto sceneSession = GetSceneSession(persistentId);
10681         if (sceneSession == nullptr) {
10682             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
10683             clearFailedIds.push_back(persistentId);
10684             continue;
10685         }
10686         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10687             TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10688             clearFailedIds.push_back(persistentId);
10689             continue;
10690         }
10691         sceneSession->Clear();
10692         TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
10693     }
10694     return WMError::WM_OK;
10695 }
10696 
UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density, bool enable)10697 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
10698     bool enable)
10699 {
10700     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
10701         width, height, density, enable);
10702 
10703     DMHookInfo dmHookInfo;
10704     dmHookInfo.width_ = width;
10705     dmHookInfo.height_ = height;
10706     dmHookInfo.density_ = density;
10707     dmHookInfo.rotation_ = 0;
10708     dmHookInfo.enableHookRotation_ = false;
10709     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10710     return WMError::WM_OK;
10711 }
10712 
UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)10713 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
10714 {
10715     TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
10716         "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
10717         hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
10718     if (enable && (uid <= 0 || hookInfo.width_ <= 0 || hookInfo.height_ <= 0 || hookInfo.density_ <= 0)) {
10719         TLOGE(WmsLogTag::WMS_LAYOUT, "App hookInfo param error.");
10720         return WMError::WM_ERROR_INVALID_PARAM;
10721     }
10722     DMHookInfo dmHookInfo;
10723     dmHookInfo.width_ = hookInfo.width_;
10724     dmHookInfo.height_ = hookInfo.height_;
10725     dmHookInfo.density_ = hookInfo.density_;
10726     dmHookInfo.rotation_ = hookInfo.rotation_;
10727     dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
10728     ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10729     return WMError::WM_OK;
10730 }
10731 
OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)10732 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
10733 {
10734     SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
10735 }
10736 
ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)10737 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
10738 {
10739     ScreenFoldData screenFoldData;
10740     WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
10741     if (ret != WMError::WM_OK) {
10742         return ret;
10743     }
10744     return CheckAndReportScreenFoldStatus(screenFoldData);
10745 }
10746 
MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo, ScreenFoldData& screenFoldData)10747 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
10748     ScreenFoldData& screenFoldData)
10749 {
10750     if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
10751         TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
10752         return WMError::WM_DO_NOTHING;
10753     }
10754 
10755     screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
10756     screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
10757     screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
10758     screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
10759     screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
10760     if (!screenFoldData.GetTypeCThermalWithUtil()) {
10761         TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
10762         return WMError::WM_DO_NOTHING;
10763     }
10764     AppExecFwk::ElementName element = {};
10765     WSError ret = GetFocusSessionElement(element);
10766     if (ret != WSError::WS_OK) {
10767         TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
10768         return WMError::WM_DO_NOTHING;
10769     }
10770     screenFoldData.SetFocusedPkgName(element.GetURI());
10771     int32_t ret_z = HiSysEventWrite(
10772         OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
10773         "FOCUS_WINDOW",
10774         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
10775         "BUNDLE_NAME", element.GetURI());
10776     if (ret_z != 0) {
10777         TLOGE(WmsLogTag::DMS, "Write FOCUS_WINDOW HiSysEvent error, ret_z: %{public}d.", ret_z);
10778     }
10779     return WMError::WM_OK;
10780 }
10781 
CheckAndReportScreenFoldStatus(ScreenFoldData& data)10782 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
10783 {
10784     static ScreenFoldData lastScreenHalfFoldData;
10785     if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10786         lastScreenHalfFoldData = data;
10787         return WMError::WM_DO_NOTHING;
10788     }
10789     WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
10790     if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10791         if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
10792             lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
10793         } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
10794             // if stay at half-fold less than 15s, combine this change with last
10795             data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
10796             data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
10797             data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
10798         }
10799         lastScreenHalfFoldData.SetInvalid();
10800     }
10801     WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
10802     return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
10803         currentScreenFoldStatusReportRet;
10804 }
10805 
10806 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData& data)10807 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
10808 {
10809     if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
10810         return WMError::WM_DO_NOTHING;
10811     }
10812 
10813     int32_t ret = HiSysEventWrite(
10814         OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
10815         "FOLDSCREEN_STATE_CHANGE",
10816         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
10817         "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
10818         "LASTFOLDSTATE", data.currentScreenFoldStatus_,
10819         "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
10820         "STATE", -1,
10821         "TIME", data.currentScreenFoldStatusDuration_,
10822         "ROTATION", data.screenRotation_,
10823         "PACKAGE", data.focusedPackageName_,
10824         "ANGLE", data.postureAngle_,
10825         "TYPECTHERMAL", data.typeCThermal_,
10826         "SCREENTHERMAL", -1,
10827         "SCANGLE", -1,
10828         "ISTENT", -1);
10829     if (ret != 0) {
10830         TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
10831         return WMError::WM_DO_NOTHING;
10832     }
10833     return WMError::WM_OK;
10834 }
10835 
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)10836 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
10837 {
10838     if (currentUserId_ != static_cast<int32_t>(userid)) {
10839         TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64"", currentUserId_, userid);
10840         return;
10841     }
10842     auto secSurfaceInfoMap = secExtensionData->GetSecData();
10843     auto task = [secSurfaceInfoMap]()-> WSError {
10844         SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
10845         return WSError::WS_OK;
10846     };
10847     taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
10848 }
10849 
RegisterSecSurfaceInfoListener()10850 void SceneSessionManager::RegisterSecSurfaceInfoListener()
10851 {
10852     auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
10853         this->UpdateSecSurfaceInfo(secExtensionData, userid);
10854     };
10855     TLOGI(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener");
10856     if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
10857         TLOGE(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener failed");
10858     }
10859 }
10860 
SetAppForceLandscapeConfig(const std::string& bundleName, const AppForceLandscapeConfig& config)10861 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
10862     const AppForceLandscapeConfig& config)
10863 {
10864     if (bundleName.empty()) {
10865         TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
10866         return WSError::WS_ERROR_NULLPTR;
10867     }
10868     std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10869     appForceLandscapeMap_[bundleName] = config;
10870     TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
10871         bundleName.c_str(), config.mode_, config.homePage_.c_str());
10872     return WSError::WS_OK;
10873 }
10874 
GetAppForceLandscapeConfig(const std::string& bundleName)10875 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
10876 {
10877     if (bundleName.empty()) {
10878         return {};
10879     }
10880     std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10881     if (appForceLandscapeMap_.empty() ||
10882         appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
10883         TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
10884         return {};
10885     }
10886     return appForceLandscapeMap_[bundleName];
10887 }
10888 
TerminateSessionByPersistentId(int32_t persistentId)10889 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
10890 {
10891     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS) ||
10892         !SessionPermission::IsSystemAppCall()) {
10893         TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
10894         return WMError::WM_ERROR_INVALID_PERMISSION;
10895     }
10896     auto sceneSession = GetSceneSession(persistentId);
10897     if (sceneSession == nullptr) {
10898         TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
10899         return WMError::WM_ERROR_INVALID_PARAM;
10900     }
10901     if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10902         TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10903         return WMError::WM_ERROR_INVALID_PARAM;
10904     }
10905     sceneSession->Clear(true);
10906     TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
10907     return WMError::WM_OK;
10908 }
10909 
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)10910 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
10911 {
10912     rootSceneProcessBackEventFunc_ = processBackEventFunc;
10913     TLOGI(WmsLogTag::WMS_EVENT, "called");
10914 }
10915 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid, const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)10916 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
10917     const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
10918 {
10919     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10920         TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
10921         return WMError::WM_ERROR_INVALID_PERMISSION;
10922     }
10923 
10924     surfaceNodeIds.clear();
10925     TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
10926     for (auto persistentId : persistentIds) {
10927         TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
10928         auto sceneSession = GetSceneSession(persistentId);
10929         if (sceneSession == nullptr) {
10930             continue;
10931         }
10932         auto callingPid = sceneSession->GetCallingPid();
10933         auto surfaceNode = sceneSession->GetSurfaceNode();
10934         if (surfaceNode != nullptr && callingPid == pid) {
10935             surfaceNodeIds.push_back(surfaceNode->GetId());
10936             auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
10937             if (leashWinSurfaceNode != nullptr) {
10938                 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
10939                 surfaceNodeIds.push_back(persistentId);
10940             }
10941         }
10942     }
10943 
10944     return WMError::WM_OK;
10945 }
10946 
RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)10947 void SceneSessionManager::RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)
10948 {
10949     auto task = [this, startZOrder, persistentIds = std::move(persistentIds)] {
10950         std::ostringstream oss;
10951         oss << "[";
10952         for (size_t i = 0; i < persistentIds.size(); i++) {
10953             int32_t persistentId = persistentIds[i];
10954             oss << persistentId;
10955             if (i < persistentIds.size() - 1) {
10956                 oss << ",";
10957             }
10958             auto sceneSession = GetSceneSession(persistentId);
10959             if (sceneSession == nullptr) {
10960                 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr persistentId = %{public}d", persistentId);
10961                 continue;
10962             }
10963             if (i > UINT32_MAX - startZOrder) {
10964                 TLOGNE(WmsLogTag::WMS_LAYOUT, "Z order overflow, stop refresh");
10965                 break;
10966             }
10967             sceneSession->SetPcScenePanel(true);
10968             sceneSession->PcUpdateZOrderAndDirty(i + startZOrder);
10969         }
10970         oss << "]";
10971         TLOGNI(WmsLogTag::WMS_LAYOUT, "RefreshPcZOrderList:%{public}s", oss.str().c_str());
10972         return WSError::WS_OK;
10973     };
10974     taskScheduler_->PostTask(task, __func__);
10975 }
10976 
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)10977 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
10978 {
10979     TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
10980     closeTargetFloatWindowFunc_ = func;
10981 }
10982 
CloseTargetFloatWindow(const std::string& bundleName)10983 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
10984 {
10985     if (!SessionPermission::IsSystemServiceCalling(false)) {
10986         TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
10987         return WMError::WM_ERROR_INVALID_PERMISSION;
10988     }
10989     auto task = [this, bundleName] {
10990         if (closeTargetFloatWindowFunc_) {
10991             TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
10992             closeTargetFloatWindowFunc_(bundleName);
10993         }
10994     };
10995     taskScheduler_->PostTask(task, "CloseTargetFloatWindow");
10996     return WMError::WM_OK;
10997 }
10998 
UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)10999 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
11000 {
11001     SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
11002 }
11003 
CloseTargetPiPWindow(const std::string& bundleName)11004 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
11005 {
11006     if (!SessionPermission::IsSystemServiceCalling(false)) {
11007         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11008         return WMError::WM_ERROR_INVALID_PERMISSION;
11009     }
11010     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11011     for (const auto& iter: sceneSessionMap_) {
11012         auto& session = iter.second;
11013         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
11014             session->GetSessionInfo().bundleName_ == bundleName) {
11015             session->NotifyCloseExistPipWindow();
11016             break;
11017         }
11018     }
11019     return WMError::WM_OK;
11020 }
11021 
GetCurrentPiPWindowInfo(std::string& bundleName)11022 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
11023 {
11024     if (!SessionPermission::IsSystemServiceCalling(false)) {
11025         TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11026         return WMError::WM_ERROR_INVALID_PERMISSION;
11027     }
11028     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11029     for (const auto& iter: sceneSessionMap_) {
11030         auto& session = iter.second;
11031         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
11032             bundleName = session->GetSessionInfo().bundleName_;
11033             return WMError::WM_OK;
11034         }
11035     }
11036     TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
11037     return WMError::WM_OK;
11038 }
11039 
SkipSnapshotForAppProcess(int32_t pid, bool skip)11040 WMError SceneSessionManager::SkipSnapshotForAppProcess(int32_t pid, bool skip)
11041 {
11042     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11043         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11044         return WMError::WM_ERROR_INVALID_PERMISSION;
11045     }
11046     TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d, skip:%{public}u", pid, skip);
11047     auto task = [this, pid, skip]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
11048         if (skip) {
11049             snapshotSkipPidSet_.insert(pid);
11050         } else {
11051             snapshotSkipPidSet_.erase(pid);
11052         }
11053         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11054         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11055             if (sceneSession == nullptr) {
11056                 continue;
11057             }
11058             if (pid == sceneSession->GetCallingPid()) {
11059                 TLOGI(WmsLogTag::DEFAULT, "send rs set snapshot skip, persistentId:%{public}d, skip:%{public}u",
11060                     persistentId, skip);
11061                 sceneSession->SetSnapshotSkip(skip);
11062             }
11063         }
11064     };
11065     taskScheduler_->PostTask(task, "SkipSnapshotForAppProcess");
11066     return WMError::WM_OK;
11067 }
11068 
RemoveProcessSnapshotSkip(int32_t pid)11069 void SceneSessionManager::RemoveProcessSnapshotSkip(int32_t pid)
11070 {
11071     if (snapshotSkipPidSet_.erase(pid) != 0) {
11072         TLOGI(WmsLogTag::DEFAULT, "process died, delete pid from snapshot skip pid set. pid:%{public}d", pid);
11073     }
11074 }
11075 
SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)11076 void SceneSessionManager::SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)
11077 {
11078     auto callingPid = sceneSession->GetCallingPid();
11079     if (snapshotSkipPidSet_.find(callingPid) != snapshotSkipPidSet_.end()) {
11080         sceneSession->SetSnapshotSkip(true);
11081     }
11082 }
11083 
SkipSnapshotByUserIdAndBundleNames(int32_t userId, const std::vector<std::string>& bundleNameList)11084 WMError SceneSessionManager::SkipSnapshotByUserIdAndBundleNames(int32_t userId,
11085     const std::vector<std::string>& bundleNameList)
11086 {
11087     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11088         TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
11089         return WMError::WM_ERROR_INVALID_PERMISSION;
11090     }
11091     TLOGI(WmsLogTag::DEFAULT, "userId:%{public}d", userId);
11092     auto task = [this, userId, bundleNameList]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
11093         snapshotSkipBundleNameSet_.clear();
11094         for (auto& bundleName : bundleNameList) {
11095             snapshotSkipBundleNameSet_.insert(std::move(bundleName));
11096         }
11097         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11098         for (const auto& [_, sceneSession] : sceneSessionMap_) {
11099             if (sceneSession == nullptr) {
11100                 continue;
11101             }
11102             const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
11103             if (snapshotSkipBundleNameSet_.find(bundleName) != snapshotSkipBundleNameSet_.end()) {
11104                 TLOGNI(WmsLogTag::DEFAULT, "set RS snapshot skip true, name:%{public}s",
11105                     bundleName.c_str());
11106                 sceneSession->SetSnapshotSkip(true);
11107                 continue;
11108             }
11109             sceneSession->SetSnapshotSkip(false);
11110         }
11111     };
11112     taskScheduler_->PostTask(task, __func__);
11113     return WMError::WM_OK;
11114 }
11115 
SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)11116 void SceneSessionManager::SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)
11117 {
11118     const std::string& name = sceneSession->GetSessionInfo().bundleName_;
11119     if (snapshotSkipBundleNameSet_.find(name) != snapshotSkipBundleNameSet_.end()) {
11120         TLOGI(WmsLogTag::DEFAULT, "set RS snapshot skip true, name:%{public}s",
11121             name.c_str());
11122         sceneSession->SetSnapshotSkip(true);
11123     }
11124 }
11125 
SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)11126 WMError SceneSessionManager::SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)
11127 {
11128     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11129         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11130         return WMError::WM_ERROR_INVALID_PERMISSION;
11131     }
11132     TLOGI(WmsLogTag::DEFAULT, "pid:%{public}d, watermarkName:%{public}s, isEnabled:%{public}u",
11133         pid, watermarkName.c_str(), isEnabled);
11134     if (isEnabled && watermarkName.empty()) {
11135         TLOGE(WmsLogTag::DEFAULT, "watermarkName is empty!");
11136         return WMError::WM_ERROR_INVALID_PARAM;
11137     }
11138     auto task = [this, pid, watermarkName, isEnabled] {
11139         if (isEnabled) {
11140             processWatermarkPidMap_.insert_or_assign(pid, watermarkName);
11141         } else {
11142             processWatermarkPidMap_.erase(pid);
11143         }
11144 
11145         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11146         for (const auto& [_, sceneSession] : sceneSessionMap_) {
11147             if (sceneSession == nullptr) {
11148                 continue;
11149             }
11150             if (pid == sceneSession->GetCallingPid()) {
11151                 sceneSession->SetWatermarkEnabled(watermarkName, isEnabled);
11152             }
11153         }
11154     };
11155     taskScheduler_->PostTask(task, __func__);
11156     return WMError::WM_OK;
11157 }
11158 
SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)11159 bool SceneSessionManager::SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)
11160 {
11161     if (auto iter = processWatermarkPidMap_.find(sceneSession->GetCallingPid());
11162         iter != processWatermarkPidMap_.end()) {
11163         sceneSession->SetWatermarkEnabled(iter->second, true);
11164         return true;
11165     }
11166     return false;
11167 }
11168 
RemoveProcessWatermarkPid(int32_t pid)11169 void SceneSessionManager::RemoveProcessWatermarkPid(int32_t pid)
11170 {
11171     if (processWatermarkPidMap_.find(pid) != processWatermarkPidMap_.end()) {
11172         TLOGI(WmsLogTag::DEFAULT, "process died, delete pid from watermark pid map. pid:%{public}d", pid);
11173         processWatermarkPidMap_.erase(pid);
11174     }
11175 }
11176 
GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)11177 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
11178 {
11179     if (!SessionPermission::IsSystemServiceCalling()) {
11180         TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11181         return WMError::WM_ERROR_INVALID_PERMISSION;
11182     }
11183     const char* const where = __func__;
11184     auto task = [this, persistentId, &hostWindowId, where]() {
11185         hostWindowId = INVALID_WINDOW_ID;
11186         sptr<Session> session = GetSceneSession(persistentId);
11187         while (session && SessionHelper::IsSubWindow(session->GetWindowType())) {
11188             session = session->GetParentSession();
11189         }
11190         if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
11191             hostWindowId = session->GetPersistentId();
11192         }
11193         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
11194             where, persistentId, hostWindowId);
11195         return WMError::WM_OK;
11196     };
11197     return taskScheduler_->PostSyncTask(task, where);
11198 }
11199 
GetMaxInstanceCount(const std::string& bundleName)11200 int32_t SceneSessionManager::GetMaxInstanceCount(const std::string& bundleName)
11201 {
11202     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11203         return MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
11204     } else {
11205         return 0;
11206     }
11207 }
11208 
GetInstanceCount(const std::string& bundleName)11209 int32_t SceneSessionManager::GetInstanceCount(const std::string& bundleName)
11210 {
11211     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11212         return MultiInstanceManager::GetInstance().GetInstanceCount(bundleName);
11213     } else {
11214         return 0;
11215     }
11216 }
11217 
GetLastInstanceKey(const std::string& bundleName)11218 std::string SceneSessionManager::GetLastInstanceKey(const std::string& bundleName)
11219 {
11220     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11221         return MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
11222     } else {
11223         return "";
11224     }
11225 }
11226 
RefreshAppInfo(const std::string& bundleName)11227 void SceneSessionManager::RefreshAppInfo(const std::string& bundleName)
11228 {
11229     if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11230         MultiInstanceManager::GetInstance().RefreshAppInfo(bundleName);
11231     }
11232 }
11233 
ReleaseForegroundSessionScreenLock()11234 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
11235 {
11236     if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11237         TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11238         return WMError::WM_ERROR_INVALID_PERMISSION;
11239     }
11240 #ifdef POWER_MANAGER_ENABLE
11241     auto task = [this] {
11242         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11243         for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11244             if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
11245                 continue;
11246             }
11247             auto res = sceneSession->keepScreenLock_->UnLock();
11248             if (res != ERR_OK) {
11249                 TLOGNE(WmsLogTag::DEFAULT,
11250                     "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
11251                     persistentId, sceneSession->GetWindowName().c_str(), res);
11252                 return WMError::WM_ERROR_INVALID_OPERATION;
11253             }
11254             TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
11255                 persistentId, sceneSession->GetWindowName().c_str());
11256         }
11257         return WMError::WM_OK;
11258     };
11259     return taskScheduler_->PostSyncTask(task, __func__);
11260 #else
11261     TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
11262     return WMError::WM_OK;
11263 #endif
11264 }
11265 
IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)11266 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
11267 {
11268     isPcOrPadFreeMultiWindowMode = (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode());
11269     return WMError::WM_OK;
11270 }
11271 } // namespace OHOS::Rosen