• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "session_manager/include/scene_session_manager.h"
17 
18 #include <cinttypes>
19 #include <csignal>
20 #include <cstdint>
21 #include <iomanip>
22 #include <map>
23 #include <memory>
24 #include <sstream>
25 #include <unistd.h>
26 
27 #include <ability_context.h>
28 #include <ability_info.h>
29 #include <ability_manager_client.h>
30 #include <bundle_mgr_interface.h>
31 #include <ipc_skeleton.h>
32 #include <iservice_registry.h>
33 #include <hisysevent.h>
34 #include <parameters.h>
35 #include "parameter.h"
36 #include <pointer_event.h>
37 #include <resource_manager.h>
38 #include <running_lock.h>
39 #include <session_info.h>
40 #include <start_options.h>
41 #include <system_ability_definition.h>
42 #include <want.h>
43 #include <hitrace_meter.h>
44 #include <transaction/rs_interfaces.h>
45 #include <transaction/rs_transaction.h>
46 #include "transaction/rs_sync_transaction_controller.h"
47 
48 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
49 #include <display_power_mgr_client.h>
50 #endif
51 
52 #ifdef POWER_MANAGER_ENABLE
53 #include <power_mgr_client.h>
54 #endif
55 
56 #ifdef RES_SCHED_ENABLE
57 #include "res_type.h"
58 #include "res_sched_client.h"
59 #endif
60 
61 #include "ability_start_setting.h"
62 #include "anr_manager.h"
63 #include "color_parser.h"
64 #include "common/include/session_permission.h"
65 #include "display_manager.h"
66 #include "image_source.h"
67 #include "interfaces/include/ws_common.h"
68 #include "interfaces/include/ws_common_inner.h"
69 #include "scene_input_manager.h"
70 #include "session/host/include/main_session.h"
71 #include "session/host/include/scb_system_session.h"
72 #include "session/host/include/scene_persistent_storage.h"
73 #include "session/host/include/session_utils.h"
74 #include "session/host/include/sub_session.h"
75 #include "session/host/include/system_session.h"
76 #include "session_helper.h"
77 #include "window_helper.h"
78 #include "session/screen/include/screen_session.h"
79 #include "screen_session_manager/include/screen_session_manager_client.h"
80 #include "singleton_container.h"
81 #include "window_manager_hilog.h"
82 #include "wm_common.h"
83 #include "wm_math.h"
84 #include "xcollie/watchdog.h"
85 #include "zidl/window_manager_agent_interface.h"
86 #include "session_manager_agent_controller.h"
87 #include "distributed_client.h"
88 #include "softbus_bus_center.h"
89 #include "window_manager.h"
90 #include "perform_reporter.h"
91 #include "pip_util.h"
92 #include "focus_change_info.h"
93 #include "anr_manager.h"
94 
95 #include "window_visibility_info.h"
96 #include "window_drawing_content_info.h"
97 #ifdef MEMMGR_WINDOW_ENABLE
98 #include "mem_mgr_client.h"
99 #include "mem_mgr_window_info.h"
100 #endif
101 
102 #ifdef EFFICIENCY_MANAGER_ENABLE
103 #include "suspend_manager_client.h"
104 #endif // EFFICIENCY_MANAGER_ENABLE
105 
106 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
107 #include "sec_comp_enhance_kit.h"
108 #endif
109 
110 #ifdef IMF_ENABLE
111 #include <input_method_controller.h>
112 #endif // IMF_ENABLE
113 
114 namespace OHOS::Rosen {
115 namespace {
116 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
117 #ifdef RES_SCHED_ENABLE
118 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
119 #endif
120 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
121 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
122 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
123 std::recursive_mutex g_instanceMutex;
124 constexpr uint32_t MAX_BRIGHTNESS = 255;
125 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
126 constexpr int32_t DEFAULT_USERID = -1;
127 constexpr int32_t SCALE_DIMENSION = 2;
128 constexpr int32_t TRANSLATE_DIMENSION = 2;
129 constexpr int32_t ROTAION_DIMENSION = 4;
130 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
131 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
132 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
133 const std::string EMPTY_DEVICE_ID = "";
134 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
135 
136 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
137 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
138 constexpr int VALUE_MAX_WIDTH = 5;
139 constexpr int ORIEN_MAX_WIDTH = 12;
140 constexpr int OFFSET_MAX_WIDTH = 8;
141 constexpr int PID_MAX_WIDTH = 8;
142 constexpr int PARENT_ID_MAX_WIDTH = 6;
143 constexpr int SCALE_MAX_WIDTH = 8;
144 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
145 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
146 const std::string ARG_DUMP_ALL = "-a";
147 const std::string ARG_DUMP_WINDOW = "-w";
148 const std::string ARG_DUMP_SCREEN = "-s";
149 const std::string ARG_DUMP_DISPLAY = "-d";
150 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
GetCurrentTime()151 std::string GetCurrentTime()
152 {
153     struct timespec tn;
154     clock_gettime(CLOCK_REALTIME, &tn);
155     uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
156         static_cast<uint64_t>(tn.tv_nsec);
157     return std::to_string(uTime);
158 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)159 int Comp(const std::pair<uint64_t, WindowVisibilityState> &a, const std::pair<uint64_t, WindowVisibilityState> &b)
160 {
161     return a.first < b.first;
162 }
163 } // namespace
164 
GetInstance()165 SceneSessionManager& SceneSessionManager::GetInstance()
166 {
167     std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
168     static SceneSessionManager* instance = nullptr;
169     if (instance == nullptr) {
170         instance = new SceneSessionManager();
171         instance->Init();
172     }
173     return *instance;
174 }
175 
SceneSessionManager()176 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
177 {
178     taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
179     currentUserId_ = DEFAULT_USERID;
180 }
181 
Init()182 void SceneSessionManager::Init()
183 {
184     constexpr uint64_t interval = 5 * 1000; // 5 second
185     auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
186     auto mainEventHandler = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
187     if (HiviewDFX::Watchdog::GetInstance().AddThread("MainThread", mainEventHandler, interval)) {
188         WLOGFW("Add thread MainThread to watchdog failed.");
189     }
190     if (HiviewDFX::Watchdog::GetInstance().AddThread(
191         SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
192         WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
193     }
194 
195     InitScheduleUtils();
196 
197     bundleMgr_ = GetBundleManager();
198     LoadWindowSceneXml();
199     sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
200     ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
201     InitPrepareTerminateConfig();
202 
203     // create handler for inner command at server
204     eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
205     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
206     if (eventHandler_ == nullptr) {
207         WLOGFE("Invalid eventHander");
208         return ;
209     }
210     int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
211     if (ret != 0) {
212         WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
213     }
214 
215     listenerController_ = std::make_shared<SessionListenerController>();
216     listenerController_->Init();
217     scbSessionHandler_ = new ScbSessionHandler();
218     AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
219     StartWindowInfoReportLoop();
220     WLOGI("SceneSessionManager init success.");
221     RegisterAppListener();
222     openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
223 }
224 
InitScheduleUtils()225 void SceneSessionManager::InitScheduleUtils()
226 {
227 #ifdef RES_SCHED_ENABLE
228     std::unordered_map<std::string, std::string> payload {
229         { "pid", std::to_string(getprocpid()) },
230         { "tid", std::to_string(getproctid()) },
231         { "uid", std::to_string(getuid()) },
232         { "bundleName", SCENE_BOARD_BUNDLE_NAME },
233     };
234     uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
235     int64_t value = 0;
236     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, value, payload);
237     auto task = []() {
238         std::unordered_map<std::string, std::string> payload{
239             {"pid", std::to_string(getpid())},
240             {"tid", std::to_string(gettid())},
241             {"uid", std::to_string(getuid())},
242             {"bundleName", SCENE_BOARD_BUNDLE_NAME},
243         };
244         uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
245         int64_t value = 0;
246         OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, value, payload);
247         WLOGFI("[WMSLife] set qos success");
248     };
249     taskScheduler_->PostAsyncTask(task, "changeQosTask");
250 #endif
251 }
252 
RegisterAppListener()253 void SceneSessionManager::RegisterAppListener()
254 {
255     appAnrListener_ = new (std::nothrow) AppAnrListener();
256     auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
257     if (appMgrClient_ == nullptr) {
258         WLOGFE("appMgrClient_ is nullptr.");
259     } else {
260         auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
261         if (flag != ERR_OK) {
262             WLOGFE("Register app debug listener failed.");
263         } else {
264             WLOGFI("Register app debug listener success.");
265         }
266     }
267 }
268 
LoadWindowSceneXml()269 void SceneSessionManager::LoadWindowSceneXml()
270 {
271     if (WindowSceneConfig::LoadConfigXml()) {
272         if (WindowSceneConfig::GetConfig().IsMap()) {
273             WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
274         }
275         ConfigWindowSceneXml();
276     } else {
277         WLOGFE("Load window scene xml failed");
278     }
279     ConfigDefaultKeyboardAnimation();
280 }
281 
InitPrepareTerminateConfig()282 void SceneSessionManager::InitPrepareTerminateConfig()
283 {
284     char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
285     int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
286         PREPARE_TERMINATE_ENABLE_SIZE);
287     WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
288     if (retSysParam > 0 && !std::strcmp(value, "true")) {
289         isPrepareTerminateEnable_ = true;
290     }
291 }
292 
ConfigWindowSceneXml()293 void SceneSessionManager::ConfigWindowSceneXml()
294 {
295     const auto& config = WindowSceneConfig::GetConfig();
296     WindowSceneConfig::ConfigItem item = config["windowEffect"];
297     if (item.IsMap()) {
298         ConfigWindowEffect(item);
299     }
300 
301     item = config["decor"];
302     if (item.IsMap()) {
303         ConfigDecor(item);
304     }
305 
306     item = config["backgroundswitch"];
307     if (item.IsInts()) {
308         auto numbers = *item.intsValue_;
309         if (numbers.size() == 1 && numbers[0] == 1) {
310             systemConfig_.backgroundswitch = true;
311         }
312     }
313     WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
314 
315     item = config["defaultWindowMode"];
316     if (item.IsInts()) {
317         auto numbers = *item.intsValue_;
318         if (numbers.size() == 1 &&
319             (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
320              numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
321             systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
322         }
323     }
324 
325     item = config["defaultMaximizeMode"];
326     if (item.IsInts()) {
327         auto numbers = *item.intsValue_;
328         if (numbers.size() == 1 &&
329             (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
330             numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
331             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
332         }
333     }
334 
335     item = config["keyboardAnimation"];
336     if (item.IsMap()) {
337         ConfigKeyboardAnimation(item);
338     }
339 
340     item = config["maxFloatingWindowSize"];
341     if (item.IsInts()) {
342         auto numbers = *item.intsValue_;
343         if (numbers.size() == 1) {
344             systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
345         }
346     }
347 
348     item = config["windowAnimation"];
349     if (item.IsMap()) {
350         ConfigWindowAnimation(item);
351     }
352 
353     item = config["startWindowTransitionAnimation"];
354     if (item.IsMap()) {
355         ConfigStartingWindowAnimation(item);
356     }
357 
358     ConfigWindowSizeLimits();
359     ConfigSnapshotScale();
360 }
361 
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)362 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
363     const ContinueState& continueState)
364 {
365     WLOGFI("run SetSessionContinueState");
366     auto task = [this, token, continueState]() {
367         sptr <SceneSession> sceneSession = FindSessionByToken(token);
368         if (sceneSession == nullptr) {
369             WLOGFI("fail to find session by token.");
370             return WSError::WS_ERROR_INVALID_PARAM;
371         }
372         sceneSession->SetSessionInfoContinueState(continueState);
373         DistributedClient dmsClient;
374         dmsClient.SetMissionContinueState(sceneSession->GetPersistentId(),
375             static_cast<AAFwk::ContinueState>(continueState));
376         WLOGFI("SetSessionContinueState sessionId:%{public}d, continueState:%{public}d",
377             sceneSession->GetPersistentId(), continueState);
378         return WSError::WS_OK;
379     };
380     return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
381 }
382 
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig)383 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig)
384 {
385     WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
386     if (item.IsBool()) {
387         systemConfig_.isSystemDecorEnable_ = item.boolValue_;
388         std::vector<std::string> supportedModes;
389         item = decorConfig["supportedMode"];
390         if (item.IsStrings()) {
391             systemConfig_.decorModeSupportInfo_ = 0;
392             supportedModes = *item.stringsValue_;
393         }
394         for (auto mode : supportedModes) {
395             if (mode == "fullscreen") {
396                 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
397             } else if (mode == "floating") {
398                 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
399             } else if (mode == "pip") {
400                 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
401             } else if (mode == "split") {
402                 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
403                     WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
404             } else {
405                 WLOGFW("Invalid supporedMode");
406                 systemConfig_.decorModeSupportInfo_ = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
407                 break;
408             }
409         }
410     }
411 }
412 
AddAlphaToColor(float alpha,std::string & color)413 static void AddAlphaToColor(float alpha, std::string& color)
414 {
415     if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
416         return;
417     }
418 
419     uint32_t alphaValue = 0xFF * alpha;
420     std::stringstream ss;
421     ss << std::hex << alphaValue;
422     std::string strAlpha = ss.str();
423     if (strAlpha.size() == 1) {
424         strAlpha.append(1, '0');
425     }
426 
427     color.insert(1, strAlpha);
428 }
429 
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)430 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
431 {
432     AppWindowSceneConfig config;
433     // config corner radius
434     WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
435     if (item.IsMap()) {
436         if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
437             appWindowSceneConfig_ = config;
438         }
439     }
440 
441     // config shadow
442     item = effectConfig["appWindows"]["shadow"]["focused"];
443     if (item.IsMap()) {
444         if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
445             appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
446         }
447     }
448 
449     item = effectConfig["appWindows"]["shadow"]["unfocused"];
450     if (item.IsMap()) {
451         if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
452             appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
453         }
454     }
455 
456     AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
457     AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
458 
459     WLOGFI("Config window effect successfully");
460 }
461 
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)462 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
463 {
464     std::map<std::string, float> stringToCornerRadius = {
465         {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
466         {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
467     };
468 
469     if (item.IsString()) {
470         auto value = item.stringValue_;
471         if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
472             out = stringToCornerRadius[value];
473             return true;
474         }
475     }
476     return false;
477 }
478 
SetEnableInputEvent(bool enabled)479 void SceneSessionManager::SetEnableInputEvent(bool enabled)
480 {
481     WLOGFI("[WMSRecover] Set enable input event: %{public}u", enabled);
482     enableInputEvent_ = enabled;
483 }
484 
IsInputEventEnabled()485 bool SceneSessionManager::IsInputEventEnabled()
486 {
487     return enableInputEvent_;
488 }
489 
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)490 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
491 {
492     WLOGFI("[WMSRecover] Number of persistentIds recovered = %{public}zu. CurrentUserId = "
493            "%{public}d",
494         recoveredPersistentIds.size(), currentUserId_);
495     std::vector<AAFwk::SessionInfo> abilitySessionInfos;
496 
497     for (auto i = 0; i < static_cast<int32_t>(recoveredPersistentIds.size()); i++) {
498         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
499         auto search = sceneSessionMap_.find(recoveredPersistentIds.at(i));
500         if (search == sceneSessionMap_.end() || search->second == nullptr) {
501             continue;
502         }
503         WLOGFD("[WMSRecover] recovered persistentId = %{public}d", search->first);
504         auto sceneSession = search->second;
505         const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
506         if (!abilitySessionInfo) {
507             WLOGFW("[WMSRecover] abilitySessionInfo is null");
508             return;
509         }
510         abilitySessionInfos.emplace_back(*abilitySessionInfo);
511     }
512     auto task = [abilitySessionInfos]() {
513         AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
514             abilitySessionInfos, SceneSessionManager::GetInstance().GetCurrentUserId());
515     };
516     return taskScheduler_->PostAsyncTask(task, "UpdateSessionInfoBySCB");
517 }
518 
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)519 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
520     WindowShadowConfig& outShadow)
521 {
522     WindowSceneConfig::ConfigItem item = shadowConfig["color"];
523     if (item.IsString()) {
524         auto color = item.stringValue_;
525         uint32_t colorValue;
526         if (!ColorParser::Parse(color, colorValue)) {
527             return false;
528         }
529         outShadow.color_ = color;
530     }
531 
532     item = shadowConfig["offsetX"];
533     if (item.IsFloats()) {
534         auto offsetX = *item.floatsValue_;
535         if (offsetX.size() != 1) {
536             return false;
537         }
538         outShadow.offsetX_ = offsetX[0];
539     }
540 
541     item = shadowConfig["offsetY"];
542     if (item.IsFloats()) {
543         auto offsetY = *item.floatsValue_;
544         if (offsetY.size() != 1) {
545             return false;
546         }
547         outShadow.offsetY_ = offsetY[0];
548     }
549 
550     item = shadowConfig["alpha"];
551     if (item.IsFloats()) {
552         auto alpha = *item.floatsValue_;
553         if (alpha.size() != 1 ||
554             (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
555             return false;
556         }
557         outShadow.alpha_ = alpha[0];
558     }
559 
560     item = shadowConfig["radius"];
561     if (item.IsFloats()) {
562         auto radius = *item.floatsValue_;
563         if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
564             return false;
565         }
566         outShadow.radius_ = radius[0];
567     }
568 
569     return true;
570 }
571 
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)572 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
573 {
574     LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
575     LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
576 
577     const auto& defaultAnimation = appWindowSceneConfig_.keyboardAnimationIn_;
578     systemConfig_.keyboardAnimationConfig_.curveType_ = defaultAnimation.curveType_;
579     systemConfig_.keyboardAnimationConfig_.curveParams_.assign({
580         defaultAnimation.ctrlX1_,
581         defaultAnimation.ctrlY1_,
582         defaultAnimation.ctrlX2_,
583         defaultAnimation.ctrlY2_,
584     });
585     systemConfig_.keyboardAnimationConfig_.durationIn_ = appWindowSceneConfig_.keyboardAnimationIn_.duration_;
586     systemConfig_.keyboardAnimationConfig_.durationOut_ = appWindowSceneConfig_.keyboardAnimationOut_.duration_;
587 }
588 
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)589 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
590     KeyboardSceneAnimationConfig& config)
591 {
592     if (item.IsMap() && item.mapValue_->count("curve")) {
593         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
594         config.curveType_ = curveType;
595         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
596             config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
597             config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
598             config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
599             config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
600         }
601     }
602 
603     const WindowSceneConfig::ConfigItem& duration = item["duration"];
604     if (duration.IsInts()) {
605         auto numbers = *duration.intsValue_;
606         if (numbers.size() == 1) {
607             config.duration_ = static_cast<uint32_t>(numbers[0]);
608         }
609     }
610 }
611 
ConfigDefaultKeyboardAnimation()612 void SceneSessionManager::ConfigDefaultKeyboardAnimation()
613 {
614     constexpr char CURVETYPE[] = "interpolatingSpring";
615     constexpr float CTRLX1 = 0;
616     constexpr float CTRLY1 = 1;
617     constexpr float CTRLX2 = 342;
618     constexpr float CTRLY2 = 37;
619     constexpr uint32_t DURATION = 150;
620 
621     if (!systemConfig_.keyboardAnimationConfig_.curveType_.empty()) {
622         return;
623     }
624 
625     systemConfig_.keyboardAnimationConfig_.curveType_ = CURVETYPE;
626     std::vector<float> keyboardCurveParams = {CTRLX1, CTRLY1, CTRLX2, CTRLY2};
627     systemConfig_.keyboardAnimationConfig_.curveParams_.assign(
628         keyboardCurveParams.begin(), keyboardCurveParams.end());;
629     systemConfig_.keyboardAnimationConfig_.durationIn_ = DURATION;
630     systemConfig_.keyboardAnimationConfig_.durationOut_ = DURATION;
631 }
632 
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)633 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
634 {
635     WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
636     if (item.IsMap() && item.mapValue_->count("curve")) {
637         const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
638         appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
639         if (curveParams.size() == CURVE_PARAM_DIMENSION) {
640             appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
641             appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
642             appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
643             appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
644         }
645     }
646     item = windowAnimationConfig["timing"]["duration"];
647     if (item.IsInts() && item.intsValue_->size() == 1) {
648         auto duration = *item.intsValue_;
649         appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
650     }
651     item = windowAnimationConfig["scale"];
652     if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
653         auto scales = *item.floatsValue_;
654         appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
655         appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
656     }
657     item = windowAnimationConfig["rotation"];
658     if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
659         auto rotations = *item.floatsValue_;
660         appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
661         appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
662         appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
663         appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
664     }
665     item = windowAnimationConfig["translate"];
666     if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
667         auto translates = *item.floatsValue_;
668         appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
669         appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
670     }
671     item = windowAnimationConfig["opacity"];
672     if (item.IsFloats() && item.floatsValue_->size() == 1) {
673         auto opacity = *item.floatsValue_;
674         appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
675     }
676 }
677 
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)678 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
679 {
680     auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
681     auto item = configItem.GetProp("enable");
682     if (item.IsBool()) {
683         config.enabled_ = item.boolValue_;
684     }
685     item = configItem["timing"];
686     if (item.IsMap() && item.mapValue_->count("curve")) {
687         config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
688     }
689     item = configItem["timing"]["duration"];
690     if (item.IsInts() && item.intsValue_->size() == 1) {
691         config.duration_ = (*item.intsValue_)[0];
692     }
693     item = configItem["opacityStart"];
694     if (item.IsFloats() && item.floatsValue_->size() == 1) {
695         config.opacityStart_ = (*item.floatsValue_)[0];
696     }
697     item = configItem["opacityEnd"];
698     if (item.IsFloats() && item.floatsValue_->size() == 1) {
699         config.opacityEnd_ = (*item.floatsValue_)[0];
700     }
701 }
702 
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)703 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
704     const WindowSceneConfig::ConfigItem& curveConfig)
705 {
706     static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
707         "linear", "spring", "interactiveSpring", "interpolatingSpring" };
708     static std::unordered_set<std::string> paramCurveSet = {
709         "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
710 
711     std::string curveName = "easeOut";
712     const auto& nameItem = curveConfig.GetProp("name");
713     if (!nameItem.IsString()) {
714         return {curveName, {}};
715     }
716 
717     std::string name = nameItem.stringValue_;
718     std::vector<float> curveParams;
719 
720     if (paramCurveSet.find(name) != paramCurveSet.end()) {
721         curveName = name;
722         curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
723         if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
724             std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
725                 curveParams.begin());
726         }
727     } else {
728         auto iter = curveSet.find(name);
729         if (iter != curveSet.end()) {
730             curveName = name;
731         }
732     }
733 
734     return {curveName, curveParams};
735 }
736 
ConfigWindowSizeLimits()737 void SceneSessionManager::ConfigWindowSizeLimits()
738 {
739     const auto& config = WindowSceneConfig::GetConfig();
740     WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
741     if (item.IsMap()) {
742         ConfigMainWindowSizeLimits(item);
743     }
744 
745     item = config["subWindowSizeLimits"];
746     if (item.IsMap()) {
747         ConfigSubWindowSizeLimits(item);
748     }
749 }
750 
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)751 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
752 {
753     auto item = mainWindowSizeConifg["miniWidth"];
754     if (item.IsInts()) {
755         auto numbers = *item.intsValue_;
756         if (numbers.size() == 1) {
757             systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
758         }
759     }
760 
761     item = mainWindowSizeConifg["miniHeight"];
762     if (item.IsInts()) {
763         auto numbers = *item.intsValue_;
764         if (numbers.size() == 1) {
765             systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
766         }
767     }
768 }
769 
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)770 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
771 {
772     auto item = subWindowSizeConifg["miniWidth"];
773     if (item.IsInts()) {
774         auto numbers = *item.intsValue_;
775         if (numbers.size() == 1) {
776             systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
777         }
778     }
779 
780     item = subWindowSizeConifg["miniHeight"];
781     if (item.IsInts()) {
782         auto numbers = *item.intsValue_;
783         if (numbers.size() == 1) {
784             systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
785         }
786     }
787 }
788 
ConfigSnapshotScale()789 void SceneSessionManager::ConfigSnapshotScale()
790 {
791     const auto& config = WindowSceneConfig::GetConfig();
792     WindowSceneConfig::ConfigItem item = config["snapshotScale"];
793     if (item.IsFloats()) {
794         auto snapshotScale = *item.floatsValue_;
795         if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
796             return;
797         }
798         snapshotScale_ = snapshotScale[0];
799     }
800 }
801 
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)802 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
803 {
804     rootSceneContextWeak_ = contextWeak;
805 }
806 
GetRootSceneSession()807 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
808 {
809     auto task = [this]() -> sptr<RootSceneSession> {
810         if (rootSceneSession_ != nullptr) {
811             return rootSceneSession_;
812         }
813         system::SetParameter("bootevent.wms.fullscreen.ready", "true");
814         rootSceneSession_ = new RootSceneSession();
815         rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
816         AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
817         return rootSceneSession_;
818     };
819 
820     return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
821 }
822 
GetSceneSession(int32_t persistentId)823 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
824 {
825     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
826     auto iter = sceneSessionMap_.find(persistentId);
827     if (iter == sceneSessionMap_.end()) {
828         WLOGFD("Error found scene session with id: %{public}d", persistentId);
829         return nullptr;
830     }
831     return iter->second;
832 }
833 
GetSceneSessionByName(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const int32_t appIndex)834 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const std::string& bundleName,
835     const std::string& moduleName, const std::string& abilityName, const int32_t appIndex)
836 {
837     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
838     for (const auto &item : sceneSessionMap_) {
839         auto sceneSession = item.second;
840         if (sceneSession->GetSessionInfo().bundleName_ == bundleName &&
841             sceneSession->GetSessionInfo().moduleName_ == moduleName &&
842             sceneSession->GetSessionInfo().abilityName_ == abilityName &&
843             sceneSession->GetSessionInfo().appIndex_ == appIndex) {
844             return sceneSession;
845         }
846     }
847     return nullptr;
848 }
849 
GetSceneSessionVectorByType(WindowType type)850 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
851 {
852     std::vector<sptr<SceneSession>> sceneSessionVector;
853     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
854     for (const auto &item : sceneSessionMap_) {
855         auto sceneSession = item.second;
856         if (sceneSession->GetWindowType() == type) {
857             sceneSessionVector.emplace_back(sceneSession);
858         }
859     }
860 
861     return sceneSessionVector;
862 }
863 
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)864 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
865     sptr<WindowSessionProperty> property)
866 {
867     if (property == nullptr) {
868         WLOGFD("[WMSDialog] Property is null, no need to update parent info");
869         return WSError::WS_ERROR_NULLPTR;
870     }
871     if (sceneSession == nullptr) {
872         WLOGFE("[WMSDialog] Session is nullptr");
873         return WSError::WS_ERROR_NULLPTR;
874     }
875     auto parentPersistentId = property->GetParentPersistentId();
876     if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
877         auto parentSession = GetSceneSession(parentPersistentId);
878         if (parentSession == nullptr) {
879             WLOGFE("[WMSDialog] Parent session is nullptr, parentPersistentId:%{public}d", parentPersistentId);
880             return WSError::WS_ERROR_NULLPTR;
881         }
882         parentSession->BindDialogSessionTarget(sceneSession);
883         parentSession->BindDialogToParentSession(sceneSession);
884         sceneSession->SetParentSession(parentSession);
885         WLOGFI("[WMSDialog] Update parent of dialog success, id %{public}d, parentId %{public}d",
886             sceneSession->GetPersistentId(), parentPersistentId);
887     }
888     return WSError::WS_OK;
889 }
890 
CreateSpecificSessionCallback()891 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
892 {
893     sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
894     if (specificCb == nullptr) {
895         WLOGFE("SpecificSessionCallback is nullptr");
896         return nullptr;
897     }
898     specificCb->onCreate_ = std::bind(&SceneSessionManager::RequestSceneSession,
899         this, std::placeholders::_1, std::placeholders::_2);
900     specificCb->onDestroy_ = std::bind(&SceneSessionManager::DestroyAndDisconnectSpecificSession,
901         this, std::placeholders::_1);
902     specificCb->onCameraFloatSessionChange_ = std::bind(&SceneSessionManager::UpdateCameraFloatWindowStatus,
903         this, std::placeholders::_1, std::placeholders::_2);
904     specificCb->onGetSceneSessionVectorByType_ = std::bind(&SceneSessionManager::GetSceneSessionVectorByType,
905         this, std::placeholders::_1);
906     specificCb->onUpdateAvoidArea_ = std::bind(&SceneSessionManager::UpdateAvoidArea, this, std::placeholders::_1);
907     specificCb->onWindowInfoUpdate_ = std::bind(&SceneSessionManager::NotifyWindowInfoChange,
908         this, std::placeholders::_1, std::placeholders::_2);
909     specificCb->onWindowInputPidChangeCallback_ = std::bind(&SceneSessionManager::NotifyMMIWindowPidChange,
910         this, std::placeholders::_1, std::placeholders::_2);
911     specificCb->onSessionTouchOutside_ = std::bind(&SceneSessionManager::NotifySessionTouchOutside,
912         this, std::placeholders::_1);
913     specificCb->onGetAINavigationBarArea_ = std::bind(&SceneSessionManager::GetAINavigationBarArea, this);
914     specificCb->onRecoveryPullPiPMainWindow_ = std::bind(&SceneSessionManager::RecoveryPullPiPMainWindow,
915         this, std::placeholders::_1, std::placeholders::_2);
916     specificCb->onOutsideDownEvent_ = std::bind(&SceneSessionManager::OnOutsideDownEvent,
917         this, std::placeholders::_1, std::placeholders::_2);
918     return specificCb;
919 }
920 
CheckWindowId(int32_t windowId,int32_t & pid)921 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t &pid)
922 {
923     auto task = [this, windowId, &pid]() -> WMError {
924         pid = INVALID_PID;
925         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
926         auto iter = sceneSessionMap_.find(windowId);
927         if (iter == sceneSessionMap_.end()) {
928             WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
929             return WMError::WM_ERROR_INVALID_WINDOW;
930         }
931         auto sceneSession = iter->second;
932         if (sceneSession == nullptr) {
933             WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
934             return WMError::WM_ERROR_INVALID_WINDOW;
935         }
936         pid = sceneSession->GetCallingPid();
937         WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
938         return WMError::WM_OK;
939     };
940     return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
941 }
942 
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)943 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
944     sptr<WindowSessionProperty> property)
945 {
946     sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
947     sptr<SceneSession> sceneSession = nullptr;
948     if (sessionInfo.isSystem_) {
949         sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
950         WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
951     } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
952         sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
953         WLOGFI("[WMSMain]Create MainSession");
954     } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
955         sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
956         WLOGFI("[WMSSub]Create SubSession, type: %{public}d", property->GetWindowType());
957     } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
958         sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
959         WLOGFI("[WMSSystem]Create SystemSession, type: %{public}d", property->GetWindowType());
960     } else {
961         WLOGFE("[WMSLife]Invalid window type");
962     }
963     if (sceneSession != nullptr) {
964         sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
965     }
966     return sceneSession;
967 }
968 
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)969 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
970     sptr<WindowSessionProperty> property)
971 {
972     if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_ &&
973         sessionInfo.bundleName_.find("hmsapp.samplemanagement") == std::string::npos) {
974         auto session = GetSceneSession(sessionInfo.persistentId_);
975         if (session != nullptr) {
976             NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
977             WLOGFD("[WMSLife] get exist session persistentId: %{public}d", sessionInfo.persistentId_);
978             return session;
979         }
980     }
981 
982     auto task = [this, sessionInfo, property]() {
983         WLOGFI("[WMSLife] RequestSceneSession, appName: [%{public}s %{public}s %{public}s]"
984             "appIndex: %{public}d, type %{public}u isSystem:%{public}u, isPersistentRecover: %{public}u",
985             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
986             sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
987             static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
988         sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
989         if (sceneSession == nullptr) {
990             WLOGFE("[WMSLife]sceneSession is nullptr!");
991             return sceneSession;
992         }
993         if (sceneSession->GetSessionProperty()) {
994             sceneSession->GetSessionProperty()->SetDisplayId(sessionInfo.screenId_);
995             WLOGFD("[WMSLife] RequestSceneSession, synchronous screenId with displayid %{public}" PRIu64"",
996                 sessionInfo.screenId_);
997         }
998         sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
999         if (sessionInfo.isSystem_) {
1000             sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1001             sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1002             auto rootContext = rootSceneContextWeak_.lock();
1003             sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1004         } else {
1005             WLOGFD("[WMSLife]RequestSceneSession, id %{public}d, bundleName: %{public}s, moduleName: %{public}s,"
1006                 "abilityName: %{public}s want:%{public}s", sceneSession->GetPersistentId(),
1007                 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1008                 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1009         }
1010         RegisterSessionExceptionFunc(sceneSession);
1011         FillSessionInfo(sceneSession);
1012         auto persistentId = sceneSession->GetPersistentId();
1013         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", persistentId);
1014         if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1015             WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
1016         }
1017         sceneSession->SetSystemConfig(systemConfig_);
1018         sceneSession->SetSnapshotScale(snapshotScale_);
1019         UpdateParentSessionForDialog(sceneSession, property);
1020         if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1021             WLOGFD("ancoSceneState: %{public}d", sceneSession->GetSessionInfo().ancoSceneState);
1022             PreHandleCollaborator(sceneSession);
1023         }
1024         {
1025             std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1026             sceneSessionMap_.insert({ persistentId, sceneSession });
1027         }
1028         PerformRegisterInRequestSceneSession(sceneSession);
1029         NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1030         WLOGFI("[WMSLife] RequestSceneSession, id: %{public}d, type: %{public}d",
1031             persistentId, sceneSession->GetWindowType());
1032         return sceneSession;
1033     };
1034     return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1035 }
1036 
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)1037 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1038 {
1039     sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
1040     if (!info) {
1041         WLOGFE("new info failed");
1042         return;
1043     }
1044     info->action_ = action;
1045     info->abilityName_ = sessionInfo.abilityName_;
1046     info->bundleName_ = sessionInfo.bundleName_;
1047     info->toScreenId_ = sessionInfo.screenId_;
1048     info->fromScreenId_ = fromScreenId;
1049     ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1050     WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
1051         info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1052 }
1053 
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)1054 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1055 {
1056     RegisterSessionSnapshotFunc(sceneSession);
1057     RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1058     RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1059     RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1060     RegisterGetStateFromManagerFunc(sceneSession);
1061     RegisterInputMethodUpdateFunc(sceneSession);
1062     RegisterInputMethodShownFunc(sceneSession);
1063     RegisterInputMethodHideFunc(sceneSession);
1064 }
1065 
UpdateSceneSessionWant(const SessionInfo & sessionInfo)1066 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1067 {
1068     if (sessionInfo.persistentId_ != 0) {
1069         auto session = GetSceneSession(sessionInfo.persistentId_);
1070         if (session != nullptr && sessionInfo.want != nullptr) {
1071             WLOGFI("get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1072             if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1073                 session->SetSessionInfoWant(sessionInfo.want);
1074                 WLOGFI("RequestSceneSession update want, persistentId:%{public}d", sessionInfo.persistentId_);
1075             } else {
1076                 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1077             }
1078         }
1079     }
1080 }
1081 
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)1082 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
1083 {
1084     if (session != nullptr) {
1085         if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1086             FillSessionInfo(session);
1087             if (CheckCollaboratorType(session->GetCollaboratorType())) {
1088                 PreHandleCollaborator(session, persistentId);
1089             }
1090         }
1091     }
1092 }
1093 
RegisterInputMethodUpdateFunc(const sptr<SceneSession> & sceneSession)1094 void SceneSessionManager::RegisterInputMethodUpdateFunc(const sptr<SceneSession>& sceneSession)
1095 {
1096     if (sceneSession == nullptr) {
1097         WLOGFE("[WMSInput] session is nullptr");
1098         return;
1099     }
1100     NotifyCallingSessionForegroundFunc onInputMethodUpdate = [this](int32_t persistentId) {
1101         this->OnInputMethodUpdate(persistentId);
1102     };
1103     sceneSession->SetNotifyCallingSessionUpdateRectFunc(onInputMethodUpdate);
1104     WLOGFD("[WMSInput] RegisterInputMethodUpdateFunc success");
1105 }
1106 
OnInputMethodUpdate(const int32_t & persistentId)1107 void SceneSessionManager::OnInputMethodUpdate(const int32_t& persistentId)
1108 {
1109     auto scnSession = GetSceneSession(persistentId);
1110     if (scnSession == nullptr) {
1111         WLOGFE("[WMSInput] Input method is null");
1112         return;
1113     }
1114     WLOGFD("[WMSInput] persistentId: %{public}d, windowType: %{public}d", persistentId, scnSession->GetWindowType());
1115     ResizeSoftInputCallingSessionIfNeed(scnSession, true);
1116 }
1117 
RegisterInputMethodShownFunc(const sptr<SceneSession> & sceneSession)1118 void SceneSessionManager::RegisterInputMethodShownFunc(const sptr<SceneSession>& sceneSession)
1119 {
1120     if (sceneSession == nullptr) {
1121         WLOGFE("[WMSInput] session is nullptr");
1122         return;
1123     }
1124     NotifyCallingSessionForegroundFunc onInputMethodShown = [this](int32_t persistentId) {
1125         this->OnInputMethodShown(persistentId);
1126     };
1127     sceneSession->SetNotifyCallingSessionForegroundFunc(onInputMethodShown);
1128     WLOGFD("[WMSInput] RegisterInputMethodShownFunc success");
1129 }
1130 
OnInputMethodShown(const int32_t & persistentId)1131 void SceneSessionManager::OnInputMethodShown(const int32_t& persistentId)
1132 {
1133     auto scnSession = GetSceneSession(persistentId);
1134     if (scnSession == nullptr) {
1135         WLOGFE("[WMSInput] scnSession is null, persistentId: %{public}d", persistentId);
1136         return;
1137     }
1138 
1139     WLOGFD("[WMSInput] persistentId: %{public}d, windowType: %{public}d", persistentId, scnSession->GetWindowType());
1140     if (callingSession_ == nullptr) {
1141         WLOGFI("[WMSInput] Calling session is null, using focusedSessionId_: %{public}d", focusedSessionId_);
1142         callingSession_ = GetSceneSession(focusedSessionId_);
1143         if (callingSession_ == nullptr) {
1144             WLOGFE("[WMSInput] Calling session obtained through focusedSessionId_ is null");
1145             return;
1146         }
1147     }
1148     callingSession_->SetTextFieldAvoidInfo(scnSession->textFieldPositionY_, scnSession->textFieldHeight_);
1149     ResizeSoftInputCallingSessionIfNeed(scnSession);
1150 }
1151 
RegisterInputMethodHideFunc(const sptr<SceneSession> & sceneSession)1152 void SceneSessionManager::RegisterInputMethodHideFunc(const sptr<SceneSession>& sceneSession)
1153 {
1154     if (sceneSession == nullptr) {
1155         WLOGFE("[WMSInput] session is nullptr");
1156         return;
1157     }
1158     NotifyCallingSessionBackgroundFunc onInputMethodHide = [this]() {
1159         this->RestoreCallingSessionSizeIfNeed();
1160         this->callingSession_ = nullptr;
1161     };
1162     sceneSession->SetNotifyCallingSessionBackgroundFunc(onInputMethodHide);
1163     WLOGFD("[WMSInput] RegisterInputMethodHideFunc success");
1164 }
1165 
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)1166 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
1167 {
1168     sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
1169     if (!abilitySessionInfo) {
1170         WLOGFE("abilitySessionInfo is nullptr");
1171         return nullptr;
1172     }
1173     auto sessionInfo = scnSession->GetSessionInfo();
1174     sptr<ISession> iSession(scnSession);
1175     abilitySessionInfo->sessionToken = iSession->AsObject();
1176     abilitySessionInfo->callerToken = sessionInfo.callerToken_;
1177     abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
1178         sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
1179     abilitySessionInfo->persistentId = scnSession->GetPersistentId();
1180     abilitySessionInfo->requestCode = sessionInfo.requestCode;
1181     abilitySessionInfo->resultCode = sessionInfo.resultCode;
1182     abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
1183     abilitySessionInfo->startSetting = sessionInfo.startSetting;
1184     abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
1185     abilitySessionInfo->userId = currentUserId_;
1186     abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
1187     if (sessionInfo.want != nullptr) {
1188         abilitySessionInfo->want = *sessionInfo.want;
1189     } else {
1190         abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
1191             sessionInfo.moduleName_);
1192     }
1193     return abilitySessionInfo;
1194 }
1195 
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)1196 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
1197 {
1198     auto task = [this, persistentId, &isPrepareTerminate]() {
1199         if (!isPrepareTerminateEnable_) { // not support prepareTerminate
1200             isPrepareTerminate = false;
1201             WLOGE("not support prepareTerminate, persistentId%{public}d", persistentId);
1202             return WSError::WS_OK;
1203         }
1204         auto scnSession = GetSceneSession(persistentId);
1205         if (scnSession == nullptr) {
1206             WLOGFE("scnSession is nullptr persistentId:%{public}d", persistentId);
1207             isPrepareTerminate = false;
1208             return WSError::WS_ERROR_NULLPTR;
1209         }
1210         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1211         if (scnSessionInfo == nullptr) {
1212             WLOGFE("scnSessionInfo is nullptr, persistentId:%{public}d", persistentId);
1213             isPrepareTerminate = false;
1214             return WSError::WS_ERROR_NULLPTR;
1215         }
1216         WLOGI("[WMSMain]PrepareTerminateAbilityBySCB persistentId:%{public}d", persistentId);
1217         auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
1218             PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
1219         WLOGI("[WMSMain]PrepareTerminateAbilityBySCB isPrepareTerminate:%{public}d errorCode:%{public}d",
1220             isPrepareTerminate, errorCode);
1221         return WSError::WS_OK;
1222     };
1223 
1224     taskScheduler_->PostSyncTask(task, "PrepareTerminate:PID:" + std::to_string(persistentId));
1225     return WSError::WS_OK;
1226 }
1227 
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)1228 std::future<int32_t> SceneSessionManager::RequestSceneSessionActivation(
1229     const sptr<SceneSession>& sceneSession, bool isNewActive)
1230 {
1231     wptr<SceneSession> weakSceneSession(sceneSession);
1232     std::shared_ptr<std::promise<int32_t>> promise = std::make_shared<std::promise<int32_t>>();
1233     auto future = promise->get_future();
1234     auto task = [this, weakSceneSession, isNewActive, promise]() {
1235         sptr<SceneSession> scnSession = weakSceneSession.promote();
1236         if (scnSession == nullptr) {
1237             WLOGFE("[WMSMain]session is nullptr");
1238             promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_NULLPTR));
1239             return WSError::WS_ERROR_INVALID_WINDOW;
1240         }
1241 
1242         auto persistentId = scnSession->GetPersistentId();
1243         scnSession->NotifyForegroundInteractiveStatus(true);
1244         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
1245         WLOGFI("[WMSMain]active persistentId: %{public}d isSystem_:%{public}u",
1246             persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1247         if (!GetSceneSession(persistentId)) {
1248             WLOGFE("[WMSMain]session is invalid with %{public}d", persistentId);
1249             promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_INVALID_SESSION));
1250             return WSError::WS_ERROR_INVALID_WINDOW;
1251         }
1252         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1253             WLOGFI("collaborator use native session");
1254             scnSession = GetSceneSession(persistentId);
1255         }
1256         auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive, promise);
1257         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
1258         return ret;
1259     };
1260     std::string taskName = "RequestSceneSessionActivation:PID:" +
1261         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
1262     taskScheduler_->PostAsyncTask(task, taskName);
1263     return future;
1264 }
1265 
RequestInputMethodCloseKeyboard(const int32_t persistentId)1266 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
1267 {
1268     auto sceneSession = GetSceneSession(persistentId);
1269     if (sceneSession == nullptr) {
1270         WLOGFE("[WMSInput] session is nullptr");
1271         return;
1272     }
1273     // When input method is shown and another app is cold started, the input method is hidden.
1274     if (!sceneSession->IsSessionValid() && callingSession_ != nullptr) {
1275         sceneSession->RequestHideKeyboard(true);
1276     }
1277 }
1278 
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive,const std::shared_ptr<std::promise<int32_t>> & promise)1279 WSError SceneSessionManager::RequestSceneSessionActivationInner(
1280     sptr<SceneSession>& scnSession, bool isNewActive, const std::shared_ptr<std::promise<int32_t>>& promise)
1281 {
1282     auto persistentId = scnSession->GetPersistentId();
1283     RequestInputMethodCloseKeyboard(persistentId);
1284     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1285         RequestSessionFocusImmediately(persistentId);
1286     }
1287     if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1288         FillSessionInfo(scnSession);
1289         PreHandleCollaborator(scnSession, persistentId);
1290     }
1291     auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1292     if (!scnSessionInfo) {
1293         promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_NULLPTR));
1294         return WSError::WS_ERROR_INVALID_WINDOW;
1295     }
1296     scnSession->NotifyActivation();
1297     scnSessionInfo->isNewWant = isNewActive;
1298     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1299         scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
1300         scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
1301     }
1302     WLOGFI("[WMSLife]RequestSceneSessionActivationInner: want info - \
1303         abilityName: %{public}s, bundleName: %{public}s, moduleName: %{public}s, uri: %{public}s",
1304         scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
1305         scnSessionInfo->want.GetElement().GetBundleName().c_str(),
1306         scnSessionInfo->want.GetElement().GetModuleName().c_str(),
1307         scnSessionInfo->want.GetElement().GetURI().c_str());
1308     int32_t errCode = ERR_OK;
1309     if (systemConfig_.backgroundswitch == false) {
1310         WLOGFI("[WMSMain]begin StartUIAbility: %{public}d isSystem:%{public}u", persistentId,
1311             static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1312         errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo);
1313     } else {
1314         WLOGFD("[WMSMain]RequestSceneSessionActivationInner: %{public}d", systemConfig_.backgroundswitch);
1315         if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
1316             scnSession->GetSessionState() == SessionState::STATE_END) {
1317             WLOGFI("[WMSMain]begin StartUIAbility: %{public}d isSystem:%{public}u", persistentId,
1318                 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1319             errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo);
1320         } else {
1321             scnSession->NotifySessionForeground(1, true);
1322         }
1323     }
1324     auto sessionInfo = scnSession->GetSessionInfo();
1325     if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1326         WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
1327     }
1328     NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
1329     promise->set_value(static_cast<int32_t>(errCode));
1330 
1331     if (errCode != ERR_OK) {
1332         WLOGFE("session activate failed. errCode: %{public}d", errCode);
1333         scnSession->NotifySessionException(scnSessionInfo, true);
1334         if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
1335             startUIAbilityErrorFunc_(
1336                 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
1337         }
1338     }
1339     return WSError::WS_OK;
1340 }
1341 
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)1342 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
1343     sptr<AAFwk::SessionInfo>& scnSessionInfo)
1344 {
1345     if (scnSession == nullptr || scnSessionInfo == nullptr) {
1346         return;
1347     }
1348     if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1349         NotifyLoadAbility(scnSession->GetCollaboratorType(),
1350             scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
1351         NotifyUpdateSessionInfo(scnSession);
1352         NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
1353         scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
1354     }
1355 }
1356 
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop)1357 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
1358     const bool isDelegator, const bool isToDesktop)
1359 {
1360     wptr<SceneSession> weakSceneSession(sceneSession);
1361     auto task = [this, weakSceneSession, isDelegator, isToDesktop]() {
1362         auto scnSession = weakSceneSession.promote();
1363         if (scnSession == nullptr) {
1364             WLOGFE("[WMSMain]session is nullptr");
1365             return WSError::WS_ERROR_NULLPTR;
1366         }
1367         auto persistentId = scnSession->GetPersistentId();
1368         WLOGFI("[WMSMain]background session persistentId: %{public}d", persistentId);
1369         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
1370         scnSession->SetActive(false);
1371 
1372         if (isToDesktop) {
1373             auto info = scnSession->GetSessionInfo();
1374             info.callerToken_ = nullptr;
1375             info.callingTokenId_ = 0;
1376             scnSession->SetSessionInfo(info);
1377         }
1378 
1379         scnSession->Background();
1380         if (!GetSceneSession(persistentId)) {
1381             WLOGFE("[WMSMain]session is invalid with %{public}d", persistentId);
1382             return WSError::WS_ERROR_INVALID_SESSION;
1383         }
1384         if (persistentId == brightnessSessionId_) {
1385             UpdateBrightness(focusedSessionId_);
1386         }
1387         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1388         if (!scnSessionInfo) {
1389             return WSError::WS_ERROR_NULLPTR;
1390         }
1391 
1392         if (systemConfig_.backgroundswitch) {
1393             WLOGFD("[WMSMain]RequestSceneSessionBackground: %{public}d", systemConfig_.backgroundswitch);
1394             scnSession->NotifySessionBackground(1, true, true);
1395         } else {
1396             WLOGFI("[WMSMain]begin MinimzeUIAbility: %{public}d isSystem:%{public}u",
1397                 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1398             if (!isDelegator) {
1399                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
1400             } else {
1401                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
1402             }
1403         }
1404 
1405         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1406             auto sessionInfo = scnSession->GetSessionInfo();
1407             WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
1408         }
1409         return WSError::WS_OK;
1410     };
1411     std::string taskName = "RequestSceneSessionBackground:PID:" +
1412         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
1413     taskScheduler_->PostAsyncTask(task, taskName);
1414     return WSError::WS_OK;
1415 }
1416 
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)1417 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
1418 {
1419     wptr<SceneSession> weakSceneSession(sceneSession);
1420     auto task = [this, weakSceneSession, interactive]() {
1421         auto scnSession = weakSceneSession.promote();
1422         if (scnSession == nullptr) {
1423             WLOGFE("session is nullptr");
1424             return;
1425         }
1426         auto persistentId = scnSession->GetPersistentId();
1427         WLOGFI("notify interactive session persistentId: %{public}d", persistentId);
1428         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
1429         if (!GetSceneSession(persistentId)) {
1430             WLOGFE("session is invalid with %{public}d", persistentId);
1431             return;
1432         }
1433         scnSession->NotifyForegroundInteractiveStatus(interactive);
1434     };
1435 
1436     taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
1437 }
1438 
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)1439 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
1440 {
1441     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
1442     if (scnSession == nullptr) {
1443         WLOGFE("[WMSDialog] scnSession is nullptr");
1444         return WSError::WS_ERROR_NULLPTR;
1445     }
1446     if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1447         WLOGFI("[WMSDialog] Begin to destroy its dialog, parentId: %{public}d", scnSession->GetPersistentId());
1448         auto dialogVec = scnSession->GetDialogVector();
1449         for (auto dialog : dialogVec) {
1450             if (dialog == nullptr) {
1451                 WLOGFE("[WMSDialog] dialog is nullptr");
1452                 continue;
1453             }
1454             auto sceneSession = GetSceneSession(dialog->GetPersistentId());
1455             if (sceneSession == nullptr) {
1456                 WLOGFE("[WMSDialog] dialog is invalid, id: %{public}d", dialog->GetPersistentId());
1457                 return WSError::WS_ERROR_INVALID_SESSION;
1458             }
1459             WindowDestroyNotifyVisibility(sceneSession);
1460             dialog->NotifyDestroy();
1461             dialog->Disconnect();
1462 
1463             auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
1464             if (dialogSceneSession != nullptr) {
1465                 dialogSceneSession->ClearSpecificSessionCbMap();
1466             }
1467             {
1468                 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1469                 sceneSessionMap_.erase(dialog->GetPersistentId());
1470                 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
1471                 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
1472             }
1473         }
1474         scnSession->ClearDialogVector();
1475         return WSError::WS_OK;
1476     }
1477     return WSError::WS_ERROR_INVALID_SESSION;
1478 }
1479 
DestroySubSession(const sptr<SceneSession> & sceneSession)1480 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
1481 {
1482     if (sceneSession == nullptr) {
1483         WLOGFW("sceneSession is nullptr");
1484         return;
1485     }
1486     for (const auto& elem : sceneSession->GetSubSession()) {
1487         if (elem != nullptr) {
1488             const auto& persistentId = elem->GetPersistentId();
1489             WLOGFI("[WMSSub] DestroySubSession, id: %{public}d", persistentId);
1490             DestroyAndDisconnectSpecificSessionInner(elem);
1491         }
1492     }
1493 }
1494 
EraseSceneSessionMapById(int32_t persistentId)1495 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
1496 {
1497     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1498     sceneSessionMap_.erase(persistentId);
1499     systemTopSceneSessionMap_.erase(persistentId);
1500     nonSystemFloatSceneSessionMap_.erase(persistentId);
1501 }
1502 
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)1503 WSError SceneSessionManager::RequestSceneSessionDestruction(
1504     const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
1505 {
1506     wptr<SceneSession> weakSceneSession(sceneSession);
1507     auto task = [this, weakSceneSession, needRemoveSession]() {
1508         auto scnSession = weakSceneSession.promote();
1509         if (scnSession == nullptr) {
1510             WLOGFE("[WMSMain]session is nullptr");
1511             return WSError::WS_ERROR_NULLPTR;
1512         }
1513         auto persistentId = scnSession->GetPersistentId();
1514         RequestSessionUnfocus(persistentId);
1515         lastUpdatedAvoidArea_.erase(persistentId);
1516         DestroyDialogWithMainWindow(scnSession);
1517         DestroySubSession(scnSession); // destroy sub session by destruction
1518         WLOGFI("[WMSMain] destroy session persistentId: %{public}d", persistentId);
1519         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
1520         if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1521             auto sessionInfo = scnSession->GetSessionInfo();
1522             WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sessionInfo.bundleName_);
1523         }
1524         WindowDestroyNotifyVisibility(scnSession);
1525         scnSession->Disconnect();
1526         if (!GetSceneSession(persistentId)) {
1527             WLOGFE("[WMSMain]session is invalid with %{public}d", persistentId);
1528             return WSError::WS_ERROR_INVALID_SESSION;
1529         }
1530         auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1531         if (!scnSessionInfo) {
1532             return WSError::WS_ERROR_NULLPTR;
1533         }
1534         scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
1535         if (scnSessionInfo->isClearSession) {
1536             scnSessionInfo->resultCode = -1;
1537         }
1538         if (scnSessionInfo->resultCode == -1) {
1539             OHOS::AAFwk::Want want;
1540             scnSessionInfo->want = want;
1541         }
1542         return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession);
1543     };
1544     std::string taskName = "RequestSceneSessionDestruction:PID:" +
1545         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
1546     taskScheduler_->PostAsyncTask(task, taskName);
1547     return WSError::WS_OK;
1548 }
1549 
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession)1550 WSError SceneSessionManager::RequestSceneSessionDestructionInner(
1551     sptr<SceneSession> &scnSession, sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession)
1552 {
1553     auto persistentId = scnSession->GetPersistentId();
1554     NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
1555     WLOGFI("[WMSMain]begin CloseUIAbility: %{public}d isSystem:%{public}u",
1556         persistentId,
1557         static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1558     AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
1559     scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
1560     if (needRemoveSession) {
1561         if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1562             NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
1563         }
1564         EraseSceneSessionMapById(persistentId);
1565     } else {
1566         // if terminate, set want to null. so start from recent, start a new one.
1567         scnSession->SetSessionInfoWant(nullptr);
1568     }
1569     if (listenerController_ != nullptr) {
1570         NotifySessionForCallback(scnSession, needRemoveSession);
1571     }
1572     scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
1573     return WSError::WS_OK;
1574 }
1575 
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)1576 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
1577     const sptr<SceneSession>& sceneSession)
1578 {
1579     if (sceneSession == nullptr || sessionStage == nullptr) {
1580         WLOGFE("[WMSLife]sessionStage or sceneSession is nullptr");
1581         return;
1582     }
1583 
1584     auto remoteObject = sessionStage->AsObject();
1585     remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
1586     if (windowDeath_ == nullptr) {
1587         WLOGFE("[WMSLife]failed to create death recipient");
1588         return;
1589     }
1590     if (!remoteObject->AddDeathRecipient(windowDeath_)) {
1591         WLOGFE("[WMSLife]failed to add death recipient");
1592         return;
1593     }
1594     WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
1595 }
1596 
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)1597 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
1598 {
1599     auto task = [this, remoteObject] {
1600         auto iter = remoteObjectMap_.find(remoteObject);
1601         if (iter == remoteObjectMap_.end()) {
1602             WLOGFE("Invalid remoteObject");
1603             return;
1604         }
1605         WLOGFD("Remote died, id: %{public}d", iter->second);
1606         auto sceneSession = GetSceneSession(iter->second);
1607         if (sceneSession == nullptr) {
1608             WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
1609             return;
1610         }
1611         DestroyAndDisconnectSpecificSessionInner(sceneSession);
1612         remoteObjectMap_.erase(iter);
1613     };
1614     taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
1615 }
1616 
CreateAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,int32_t & persistentId,sptr<ISession> & session,sptr<IRemoteObject> token)1617 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
1618     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1619     sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
1620     sptr<IRemoteObject> token)
1621 {
1622     if (property == nullptr) {
1623         WLOGFE("property is nullptr");
1624         return WSError::WS_ERROR_NULLPTR;
1625     }
1626 
1627     if (!CheckSystemWindowPermission(property)) {
1628         WLOGFE("create system window permission denied!");
1629         return WSError::WS_ERROR_NOT_SYSTEM_APP;
1630     }
1631 
1632     // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
1633     if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
1634         WLOGFE("The alarm window has been deprecated!");
1635         return WSError::WS_ERROR_INVALID_WINDOW;
1636     }
1637 
1638     WLOGFI("[WMSLife] create specific start, name: %{public}s, type: %{public}d",
1639         property->GetWindowName().c_str(), property->GetWindowType());
1640 
1641     // Get pid and uid before posting task.
1642     auto pid = IPCSkeleton::GetCallingRealPid();
1643     auto uid = IPCSkeleton::GetCallingUid();
1644     auto task = [this, sessionStage, eventChannel, surfaceNode, property,
1645                     &persistentId, &session, token, pid, uid]() {
1646         if (property == nullptr) {
1647             return WSError::WS_ERROR_NULLPTR;
1648         }
1649         const auto& type = property->GetWindowType();
1650         // create specific session
1651         SessionInfo info;
1652         info.windowType_ = static_cast<uint32_t>(type);
1653         ClosePipWindowIfExist(type);
1654         sptr<SceneSession> newSession = RequestSceneSession(info, property);
1655         if (newSession == nullptr) {
1656             WLOGFE("[WMSSub][WMSSystem] session is nullptr");
1657             return WSError::WS_ERROR_NULLPTR;
1658         }
1659         auto errCode = newSession->Connect(
1660             sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
1661         if (property) {
1662             persistentId = property->GetPersistentId();
1663         }
1664 
1665         NotifyCreateSpecificSession(newSession, property, type);
1666         session = newSession;
1667         AddClientDeathRecipient(sessionStage, newSession);
1668         WLOGFI("[WMSLife] create specific session success, id: %{public}d, parentId: %{public}d, type: %{public}d",
1669             newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
1670         return errCode;
1671     };
1672 
1673     return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
1674 }
1675 
ClosePipWindowIfExist(WindowType type)1676 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
1677 {
1678     if (type != WindowType::WINDOW_TYPE_PIP) {
1679         return;
1680     }
1681     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1682     for (const auto& iter: sceneSessionMap_) {
1683         auto& session = iter.second;
1684         if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1685             session->NotifyCloseExistPipWindow();
1686             break;
1687         }
1688     }
1689 }
1690 
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)1691 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
1692 {
1693     WindowType type = property->GetWindowType();
1694     if (!WindowHelper::IsSystemWindow(type)) {
1695         // type is not system
1696         return true;
1697     }
1698     if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && SessionPermission::IsStartedByInputMethod()) {
1699         // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
1700         WLOGFD("check create permission success, input method app create input method window.");
1701         return true;
1702     }
1703     if (type == WindowType::WINDOW_TYPE_DRAGGING_EFFECT ||
1704         type == WindowType::WINDOW_TYPE_TOAST || type == WindowType::WINDOW_TYPE_DIALOG ||
1705         type == WindowType::WINDOW_TYPE_PIP) {
1706         // some system types could be created by normal app
1707         return true;
1708     }
1709     if (type == WindowType::WINDOW_TYPE_FLOAT &&
1710         SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
1711         // WINDOW_TYPE_FLOAT could be created with the corresponding permission
1712         return true;
1713     }
1714     if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
1715         WLOGFD("check create permission success, create with system calling.");
1716         return true;
1717     }
1718     WLOGFE("check system window permission failed.");
1719     return false;
1720 }
1721 
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)1722 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
1723 {
1724     WLOGFI("[WMSRecover] Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
1725            "%{public}d", alivePersistentIds.size(), currentUserId_);
1726     alivePersistentIds_ = alivePersistentIds;
1727 }
1728 
isNeedRecover(const int32_t persistentId)1729 bool SceneSessionManager::isNeedRecover(const int32_t persistentId)
1730 {
1731     auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
1732     if (it == alivePersistentIds_.end()) {
1733         WLOGFW("[WMSRecover] recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
1734         return false;
1735     }
1736     return true;
1737 }
1738 
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)1739 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
1740     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1741     sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
1742 {
1743     if (property == nullptr) {
1744         WLOGFE("[WMSRecover] property is nullptr");
1745         return WSError::WS_ERROR_NULLPTR;
1746     }
1747     if (property->GetParentPersistentId() > 0 && !isNeedRecover(property->GetParentPersistentId())) {
1748         return WSError::WS_ERROR_INVALID_PARAM;
1749     }
1750     auto pid = IPCSkeleton::GetCallingPid();
1751     auto uid = IPCSkeleton::GetCallingUid();
1752     auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
1753         // recover specific session
1754         const auto& type = property->GetWindowType();
1755         SessionInfo info = property->GetSessionInfo();
1756         info.isPersistentRecover_ = true;
1757         info.persistentId_ = property->GetPersistentId();
1758         info.windowMode = static_cast<int32_t>(property->GetWindowMode());
1759         info.windowType_ = static_cast<uint32_t>(type);
1760         info.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
1761         info.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN) ? SessionState::STATE_ACTIVE
1762                                                                                       : SessionState::STATE_BACKGROUND;
1763 
1764         WLOGI("[WMSRecover] RecoverAndConnectSpecificSession windowName = %{public}s, windowMode = %{public}d, "
1765               "windowType = %{public}u, persistentId = %{public}d, windowState = %{public}u, "
1766               "callingWindowId = %{public}" PRIu32, property->GetWindowName().c_str(), info.windowMode,
1767               info.windowType_, info.persistentId_, property->GetWindowState(), property->GetCallingWindow());
1768 
1769         ClosePipWindowIfExist(type);
1770         sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
1771         if (sceneSession == nullptr) {
1772             WLOGFE("[WMSRecover] RequestSceneSession failed");
1773             return WSError::WS_ERROR_NULLPTR;
1774         }
1775 
1776         auto persistentId = sceneSession->GetPersistentId();
1777         if (persistentId != info.persistentId_) {
1778             WLOGFW("[WMSRecover] PersistentId changed, from %{public}" PRId32 " to %{public}" PRId32,
1779                 info.persistentId_, persistentId);
1780         }
1781 
1782         auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
1783         if (errCode != WSError::WS_OK) {
1784             WLOGFE("[WMSRecover] SceneSession reconnect failed");
1785             EraseSceneSessionMapById(persistentId);
1786             return errCode;
1787         }
1788 
1789         NotifyCreateSpecificSession(sceneSession, property, type);
1790         CacheSubSessionForRecovering(sceneSession, property);
1791         RecoverWindowSessionProperty(sceneSession, property);
1792         AddClientDeathRecipient(sessionStage, sceneSession);
1793         session = sceneSession;
1794         return errCode;
1795     };
1796 
1797     return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
1798 }
1799 
NotifyRecoveringFinished()1800 void SceneSessionManager::NotifyRecoveringFinished()
1801 {
1802     taskScheduler_->PostAsyncTask([this]() {
1803             WLOGFI("[WMSRecover] RecoverFinished clear recoverSubSessionCacheMap");
1804             recoveringFinished_ = true;
1805             recoverSubSessionCacheMap_.clear();
1806         }, "NotifyRecoveringFinished");
1807 }
1808 
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)1809 void SceneSessionManager::CacheSubSessionForRecovering(
1810     sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
1811 {
1812     if (recoveringFinished_) {
1813         WLOGFW("[WMSRecover] recovering is finished");
1814         return;
1815     }
1816 
1817     if (sceneSession == nullptr || property == nullptr) {
1818         WLOGFE("[WMSRecover] sceneSession or property is nullptr");
1819         return;
1820     }
1821 
1822     auto windowType = property->GetWindowType();
1823     if (!SessionHelper::IsSubWindow(windowType)) {
1824         return;
1825     }
1826 
1827     auto persistentId = property->GetParentPersistentId();
1828     if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
1829         return;
1830     }
1831 
1832     WLOGFI("[WMSRecover] Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
1833         sceneSession->GetPersistentId(), persistentId);
1834 
1835     if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
1836         recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
1837     } else {
1838         recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
1839     }
1840 }
1841 
RecoverCachedSubSession(int32_t persistentId)1842 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
1843 {
1844     auto iter = recoverSubSessionCacheMap_.find(persistentId);
1845     if (iter == recoverSubSessionCacheMap_.end()) {
1846         return;
1847     }
1848 
1849     WLOGFI("[WMSRecover] RecoverCachedSubSession persistentId = %{public}" PRId32, persistentId);
1850     for (auto& sceneSession : iter->second) {
1851         NotifyCreateSubSession(persistentId, sceneSession);
1852     }
1853     recoverSubSessionCacheMap_.erase(iter);
1854 }
1855 
RecoverWindowSessionProperty(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)1856 void SceneSessionManager::RecoverWindowSessionProperty(
1857     sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
1858 {
1859     if (sceneSession == nullptr || property == nullptr) {
1860         WLOGFE("[WMSRecover] sceneSession or property is nullptr");
1861         return;
1862     }
1863 
1864     auto windowType = property->GetWindowType();
1865     if (windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1866         RelayoutKeyBoard(sceneSession);
1867         callingWindowId_ = property->GetCallingWindow();
1868         const auto& callingSession = GetSceneSession(static_cast<int32_t>(callingWindowId_));
1869         if (callingSession != nullptr) {
1870             WLOGFI("[WMSRecover] NotifyOccupiedAreaChangeInfo after inputMethod session recovered,"
1871                 "persistentId = %{public}" PRId32, callingSession->GetPersistentId());
1872             sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo();
1873             callingSession->NotifyOccupiedAreaChangeInfo(info);
1874         }
1875     } else {
1876         auto persistentId = sceneSession->GetPersistentId();
1877         if (persistentId == static_cast<int32_t>(callingWindowId_)) {
1878             WLOGFI("[WMSRecover] NotifyOccupiedAreaChangeInfo after calling session recovered,"
1879                 "persistentId = %{public}" PRId32, persistentId);
1880             sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo();
1881             sceneSession->NotifyOccupiedAreaChangeInfo(info);
1882         }
1883     }
1884 
1885     if (listenerController_ != nullptr) {
1886         WLOGFI("[WMSRecover] NotifySessionUnfocused");
1887         listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
1888     }
1889 }
1890 
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)1891 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
1892     const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1893     sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
1894 {
1895     if (property == nullptr) {
1896         WLOGFE("[WMSRecover] property is nullptr!");
1897         return WSError::WS_ERROR_NULLPTR;
1898     }
1899     if (!isNeedRecover(property->GetPersistentId())) {
1900         return WSError::WS_ERROR_INVALID_PARAM;
1901     }
1902     SessionInfo sessionInfo = property->GetSessionInfo();
1903     sessionInfo.persistentId_ = property->GetPersistentId();
1904     sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
1905     sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
1906     sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
1907     WindowState windowState = property->GetWindowState();
1908     WLOGFI("[WMSRecover] Recover and reconnect sceneSession with: bundleName=%{public}s, moduleName=%{public}s, "
1909            "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
1910            "windowState=%{public}u",
1911         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1912         sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, static_cast<uint32_t>(windowState));
1913     sptr<SceneSession> sceneSession = nullptr;
1914     if (SessionHelper::IsMainWindow(property->GetWindowType())) {
1915         sceneSession = RequestSceneSession(sessionInfo, nullptr);
1916     } else {
1917         sceneSession = RequestSceneSession(sessionInfo, property);
1918     }
1919     if (sceneSession == nullptr) {
1920         WLOGFE("[WMSRecover] Request sceneSession failed");
1921         return WSError::WS_ERROR_NULLPTR;
1922     }
1923     auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token,
1924         IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
1925     if (ret != WSError::WS_OK) {
1926         WLOGFE("[WMSRecover] Reconnect failed");
1927         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1928         sceneSessionMap_.erase(sessionInfo.persistentId_);
1929         return ret;
1930     }
1931     sessionInfo.sessionState_ = sceneSession->GetSessionState();
1932     if (recoverSceneSessionFunc_) {
1933         recoverSceneSessionFunc_(sceneSession, sessionInfo);
1934     } else {
1935         WLOGFE("[WMSRecover] recoverSceneSessionFunc_ is null");
1936         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1937         sceneSessionMap_.erase(sessionInfo.persistentId_);
1938         return WSError::WS_ERROR_NULLPTR;
1939     }
1940     RecoverWindowSessionProperty(sceneSession, property);
1941     session = sceneSession;
1942     return WSError::WS_OK;
1943 }
1944 
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)1945 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
1946 {
1947     WLOGFI("[WMSRecover] SetRecoverSceneSessionListener");
1948     recoverSceneSessionFunc_ = func;
1949 }
1950 
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)1951 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
1952 {
1953     createSystemSessionFunc_ = func;
1954 }
1955 
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)1956 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
1957     const NotifyCreateSubSessionFunc& func)
1958 {
1959     WLOGFI("[WMSSub] RegisterCreateSubSessionListener, id: %{public}d", persistentId);
1960     auto task = [this, persistentId, func]() {
1961         auto iter = createSubSessionFuncMap_.find(persistentId);
1962         if (iter == createSubSessionFuncMap_.end()) {
1963             createSubSessionFuncMap_.insert(std::make_pair(persistentId, func));
1964             RecoverCachedSubSession(persistentId);
1965         } else {
1966             WLOGFW("[WMSSub] CreateSubSessionListener is existed, id: %{public}d", persistentId);
1967         }
1968         return WMError::WM_OK;
1969     };
1970     taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
1971 }
1972 
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)1973 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
1974     sptr<WindowSessionProperty> property, const WindowType& type)
1975 {
1976     if (newSession == nullptr) {
1977         WLOGFE("newSession is nullptr");
1978         return;
1979     }
1980     if (property == nullptr) {
1981         WLOGFE("property is nullptr");
1982         return;
1983     }
1984     if (SessionHelper::IsSystemWindow(type)) {
1985         if ((type == WindowType::WINDOW_TYPE_TOAST) || (type == WindowType::WINDOW_TYPE_FLOAT)) {
1986             auto parentSession = GetSceneSession(property->GetParentPersistentId());
1987             if (parentSession != nullptr) {
1988                 newSession->SetParentSession(parentSession);
1989             }
1990         }
1991         if (createSystemSessionFunc_ && type != WindowType::WINDOW_TYPE_DIALOG) {
1992             createSystemSessionFunc_(newSession);
1993             WLOGFD("[WMSLife] Create system session, id:%{public}d, type: %{public}d",
1994                 newSession->GetPersistentId(), type);
1995         } else {
1996             WLOGFW("[WMSLife] Didn't create jsSceneSession for this system type, id:%{public}d, "
1997                 "type: %{public}d", newSession->GetPersistentId(), type);
1998             return;
1999         }
2000     } else if (SessionHelper::IsSubWindow(type)) {
2001         NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2002         WLOGFD("[WMSLife] Notify sub jsSceneSession, id:%{public}d, parentId: %{public}d, type: %{public}d",
2003             newSession->GetPersistentId(), property->GetParentPersistentId(), type);
2004     } else {
2005         WLOGFW("[WMSLife] Invalid session type, id:%{public}d, type: %{public}d",
2006             newSession->GetPersistentId(), type);
2007     }
2008 }
2009 
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session)2010 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session)
2011 {
2012     if (session == nullptr) {
2013         WLOGFE("[WMSLife] SubSession is nullptr");
2014         return;
2015     }
2016     auto iter = createSubSessionFuncMap_.find(persistentId);
2017     if (iter == createSubSessionFuncMap_.end()) {
2018         WLOGFW("[WMSLife] Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
2019         return;
2020     }
2021 
2022     auto parentSession = GetSceneSession(persistentId);
2023     if (parentSession == nullptr) {
2024         WLOGFE("[WMSLife] Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
2025             persistentId, session->GetPersistentId());
2026         return;
2027     }
2028     parentSession->AddSubSession(session);
2029     session->SetParentSession(parentSession);
2030     if (iter->second) {
2031         iter->second(session);
2032     }
2033     WLOGFD("[WMSLife] NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
2034         persistentId, session->GetPersistentId());
2035 }
2036 
UnregisterCreateSubSessionListener(int32_t persistentId)2037 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
2038 {
2039     WLOGFI("[WMSSub] UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
2040     auto task = [this, persistentId]() {
2041         auto iter = createSubSessionFuncMap_.find(persistentId);
2042         if (iter != createSubSessionFuncMap_.end()) {
2043             createSubSessionFuncMap_.erase(persistentId);
2044         } else {
2045             WLOGFW("[WMSSub] Can't find CreateSubSessionListener, id: %{public}d", persistentId);
2046         }
2047         return WMError::WM_OK;
2048     };
2049     taskScheduler_->PostSyncTask(task);
2050 }
2051 
NotifyStatusBarEnabledChange(bool enable)2052 void SceneSessionManager::NotifyStatusBarEnabledChange(bool enable)
2053 {
2054     WLOGFI("NotifyStatusBarEnabledChange enable %{public}d", enable);
2055     auto task = [this, enable]() {
2056         if (statusBarEnabledChangeFunc_) {
2057             statusBarEnabledChangeFunc_(enable);
2058         }
2059         return WMError::WM_OK;
2060     };
2061     taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
2062 }
2063 
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)2064 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
2065 {
2066     WLOGFD("SetStatusBarEnabledChangeListener");
2067     if (!func) {
2068         WLOGFD("set func is null");
2069     }
2070     statusBarEnabledChangeFunc_ = func;
2071     NotifyStatusBarEnabledChange(gestureNavigationEnabled_);
2072 }
2073 
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)2074 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
2075     const ProcessGestureNavigationEnabledChangeFunc& func)
2076 {
2077     WLOGFD("SetGestureNavigationEnabledChangeListener");
2078     if (!func) {
2079         WLOGFD("set func is null");
2080     }
2081     gestureNavigationEnabledChangeFunc_ = func;
2082 }
2083 
OnOutsideDownEvent(int32_t x,int32_t y)2084 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
2085 {
2086     WLOGFD("OnOutsideDownEvent x = %{public}d, y = %{public}d", x, y);
2087     if (outsideDownEventFunc_) {
2088         outsideDownEventFunc_(x, y);
2089     }
2090 }
2091 
NotifySessionTouchOutside(int32_t persistentId)2092 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
2093 {
2094     auto task = [this, persistentId]() {
2095         int32_t callingSessionId = persistentId;
2096         auto sceneSession = GetSceneSession(persistentId);
2097         if (callingSession_ != nullptr && sceneSession != nullptr &&
2098             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2099             callingSessionId = callingSession_->GetPersistentId();
2100         }
2101         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2102         for (const auto &item : sceneSessionMap_) {
2103             sceneSession = item.second;
2104             if (sceneSession == nullptr) {
2105                 continue;
2106             }
2107             if (!(sceneSession->IsVisible() ||
2108                 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
2109                 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
2110                 continue;
2111             }
2112             auto sessionId = sceneSession->GetPersistentId();
2113             if ((!sceneSession->CheckOutTouchOutsideRegister()) &&
2114                 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
2115                 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
2116                 continue;
2117             }
2118             if (sessionId == callingSessionId || sessionId == persistentId) {
2119                 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
2120                 continue;
2121             }
2122             sceneSession->NotifyTouchOutside();
2123         }
2124     };
2125 
2126     taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
2127     return;
2128 }
2129 
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)2130 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
2131 {
2132     WLOGFD("SetOutsideDownEventListener");
2133     outsideDownEventFunc_ = func;
2134 }
2135 
DestroyAndDisconnectSpecificSessionInner(sptr<SceneSession> sceneSession)2136 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(sptr<SceneSession> sceneSession)
2137 {
2138     if (sceneSession == nullptr) {
2139         return WSError::WS_ERROR_NULLPTR;
2140     }
2141     const auto& persistentId = sceneSession->GetPersistentId();
2142     auto ret = sceneSession->UpdateActiveStatus(false);
2143     WindowDestroyNotifyVisibility(sceneSession);
2144     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
2145         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
2146         if (parentSession == nullptr) {
2147             WLOGFE("[WMSSystem][WMSDialog] Dialog not bind parent");
2148         } else {
2149             parentSession->RemoveDialogToParentSession(sceneSession);
2150         }
2151         sceneSession->NotifyDestroy();
2152     }
2153     ret = sceneSession->Disconnect();
2154     sceneSession->ClearSpecificSessionCbMap();
2155     if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
2156         auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
2157         if (parentSession != nullptr) {
2158             WLOGFD("[WMSSub] Find parentSession, id: %{public}d", persistentId);
2159             parentSession->RemoveSubSession(persistentId);
2160         } else {
2161             WLOGFW("[WMSSub] ParentSession is nullptr, id: %{public}d", persistentId);
2162         }
2163     }
2164     {
2165         std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2166         sceneSessionMap_.erase(persistentId);
2167         systemTopSceneSessionMap_.erase(persistentId);
2168         nonSystemFloatSceneSessionMap_.erase(persistentId);
2169         UnregisterCreateSubSessionListener(persistentId);
2170     }
2171     WLOGFI("[WMSLife] Destroy specific session end, id: %{public}d", persistentId);
2172     return ret;
2173 }
2174 
DestroyAndDisconnectSpecificSession(const int32_t & persistentId)2175 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t& persistentId)
2176 {
2177     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
2178     auto task = [this, persistentId, callingPid]() {
2179         WLOGFI("[WMSLife] Destroy specific session start, id: %{public}d", persistentId);
2180         auto sceneSession = GetSceneSession(persistentId);
2181         if (sceneSession == nullptr) {
2182             return WSError::WS_ERROR_NULLPTR;
2183         }
2184 
2185         if (callingPid != sceneSession->GetCallingPid()) {
2186             WLOGFE("[WMSLife] Permission denied, not destroy by the same process");
2187             return WSError::WS_ERROR_INVALID_PERMISSION;
2188         }
2189         return DestroyAndDisconnectSpecificSessionInner(sceneSession);
2190     };
2191 
2192     return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
2193 }
2194 
GetWindowSceneConfig() const2195 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
2196 {
2197     return appWindowSceneConfig_;
2198 }
2199 
ProcessBackEvent()2200 WSError SceneSessionManager::ProcessBackEvent()
2201 {
2202     auto task = [this]() {
2203         auto session = GetSceneSession(focusedSessionId_);
2204         if (!session) {
2205             WLOGFE("session is nullptr: %{public}d", focusedSessionId_);
2206             return WSError::WS_ERROR_INVALID_SESSION;
2207         }
2208         WLOGFI("ProcessBackEvent session persistentId: %{public}d", focusedSessionId_);
2209         if (needBlockNotifyFocusStatusUntilForeground_) {
2210             WLOGFD("RequestSessionBack when start session");
2211             session->RequestSessionBack(false);
2212             return WSError::WS_OK;
2213         }
2214         session->ProcessBackEvent();
2215         return WSError::WS_OK;
2216     };
2217 
2218     taskScheduler_->PostAsyncTask(task, "ProcessBackEvent");
2219     return WSError::WS_OK;
2220 }
2221 
CleanUserMap()2222 void SceneSessionManager::CleanUserMap()
2223 {
2224     std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2225     WLOGFI("CleanUserMap in size = %{public}zu", sceneSessionMap_.size());
2226     auto iter = sceneSessionMap_.begin();
2227     while (iter != sceneSessionMap_.end()) {
2228         if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_ &&
2229             iter->second->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2230             iter = sceneSessionMap_.erase(iter);
2231         } else {
2232             iter++;
2233         }
2234     }
2235     WLOGFI("CleanUserMap out size = %{public}zu", sceneSessionMap_.size());
2236 
2237     WLOGFI("Clean systemTopSceneSessionMap in size = %{public}zu", systemTopSceneSessionMap_.size());
2238     iter = systemTopSceneSessionMap_.begin();
2239     while (iter != systemTopSceneSessionMap_.end()) {
2240         if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_) {
2241             iter = systemTopSceneSessionMap_.erase(iter);
2242         } else {
2243             iter++;
2244         }
2245     }
2246     WLOGFI("Clean systemTopSceneSessionMap out size = %{public}zu", systemTopSceneSessionMap_.size());
2247     WLOGFI("Clean nonSystemFloatSceneSessionMap in size = %{public}zu", nonSystemFloatSceneSessionMap_.size());
2248     iter = nonSystemFloatSceneSessionMap_.begin();
2249     while (iter != nonSystemFloatSceneSessionMap_.end()) {
2250         if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_) {
2251             iter = nonSystemFloatSceneSessionMap_.erase(iter);
2252         } else {
2253             iter++;
2254         }
2255     }
2256     WLOGFI("Clean nonSystemFloatSceneSessionMap out size = %{public}zu", nonSystemFloatSceneSessionMap_.size());
2257 }
2258 
SwitchUser(int32_t oldUserId,int32_t newUserId,std::string & fileDir)2259 WSError SceneSessionManager::SwitchUser(int32_t oldUserId, int32_t newUserId, std::string &fileDir)
2260 {
2261     if (oldUserId != currentUserId_ || oldUserId == newUserId || fileDir.empty()) {
2262         WLOGFE("SwitchUser params invalid");
2263         return WSError::WS_DO_NOTHING;
2264     }
2265     WLOGFD("SwitchUser oldUserId : %{public}d newUserId : %{public}d path : %{public}s",
2266         oldUserId, newUserId, fileDir.c_str());
2267     auto task = [this, newUserId, &fileDir]() {
2268         ScenePersistence::CreateSnapshotDir(fileDir);
2269         ScenePersistence::CreateUpdatedIconDir(fileDir);
2270         currentUserId_ = newUserId;
2271         {
2272             std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2273             for (const auto &item : sceneSessionMap_) {
2274                 auto scnSession = item.second;
2275                 auto persistentId = scnSession->GetPersistentId();
2276                 scnSession->SetActive(false);
2277                 scnSession->Background();
2278                 if (persistentId == brightnessSessionId_) {
2279                     UpdateBrightness(focusedSessionId_);
2280                 }
2281                 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2282                 if (!scnSessionInfo) {
2283                     return WSError::WS_ERROR_NULLPTR;
2284                 }
2285                 WLOGFI("[WMSMain]begin MinimizeUIAbility newUserId : %{public}d persistentId: %{public}d",
2286                     newUserId, persistentId);
2287                 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2288             }
2289         }
2290         CleanUserMap();
2291         return WSError::WS_OK;
2292     };
2293     taskScheduler_->PostSyncTask(task, "SwitchUser");
2294     return WSError::WS_OK;
2295 }
2296 
GetBundleManager()2297 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
2298 {
2299     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2300     if (systemAbilityMgr == nullptr) {
2301         WLOGFE("Failed to get SystemAbilityManager.");
2302         return nullptr;
2303     }
2304 
2305     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
2306     if (bmsObj == nullptr) {
2307         WLOGFE("Failed to get BundleManagerService.");
2308         return nullptr;
2309     }
2310 
2311     return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
2312 }
2313 
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)2314 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
2315     const AppExecFwk::AbilityInfo& abilityInfo)
2316 {
2317     auto context = rootSceneContextWeak_.lock();
2318     if (!context) {
2319         WLOGFE("context is nullptr.");
2320         return nullptr;
2321     }
2322     auto resourceMgr = context->GetResourceManager();
2323     if (!resourceMgr) {
2324         WLOGFE("resourceMgr is nullptr.");
2325         return nullptr;
2326     }
2327     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
2328     if (!resConfig) {
2329         WLOGFE("resConfig is nullptr.");
2330         return nullptr;
2331     }
2332     resourceMgr->GetResConfig(*resConfig);
2333     resourceMgr = Global::Resource::CreateResourceManager(
2334         abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
2335     if (!resourceMgr) {
2336         WLOGFE("resourceMgr is nullptr.");
2337         return nullptr;
2338     }
2339     resourceMgr->UpdateResConfig(*resConfig);
2340 
2341     std::string loadPath;
2342     if (!abilityInfo.hapPath.empty()) { // zipped hap
2343         loadPath = abilityInfo.hapPath;
2344     } else {
2345         loadPath = abilityInfo.resourcePath;
2346     }
2347 
2348     if (!resourceMgr->AddResource(loadPath.c_str())) {
2349         WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
2350     }
2351     return resourceMgr;
2352 }
2353 
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)2354 void SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
2355     std::string& path, uint32_t& bgColor)
2356 {
2357     auto resourceMgr = GetResourceManager(abilityInfo);
2358     if (!resourceMgr) {
2359         WLOGFE("resourceMgr is nullptr.");
2360         return;
2361     }
2362 
2363     if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
2364         WLOGFW("Failed to get background color id %{public}d.", abilityInfo.startWindowBackgroundId);
2365     }
2366 
2367     if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
2368         WLOGFE("Failed to get icon id %{public}d.", abilityInfo.startWindowIconId);
2369         return;
2370     }
2371 
2372     if (!abilityInfo.hapPath.empty()) { // zipped hap
2373         auto pos = path.find_last_of('.');
2374         if (pos == std::string::npos) {
2375             WLOGFE("Format error, path %{private}s.", path.c_str());
2376             return;
2377         }
2378         path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
2379     }
2380 }
2381 
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)2382 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
2383 {
2384     if (!bundleMgr_) {
2385         WLOGFE("bundleMgr_ is nullptr.");
2386         return;
2387     }
2388     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
2389     AAFwk::Want want;
2390     want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
2391     AppExecFwk::AbilityInfo abilityInfo;
2392     if (!bundleMgr_->QueryAbilityInfo(
2393         want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
2394         WLOGFE("Get ability info from BMS failed!");
2395         return;
2396     }
2397 
2398     GetStartupPageFromResource(abilityInfo, path, bgColor);
2399     WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
2400         abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
2401 }
2402 
FillSessionInfo(sptr<SceneSession> & sceneSession)2403 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
2404 {
2405     auto sessionInfo = sceneSession->GetSessionInfo();
2406     if (sessionInfo.bundleName_.empty()) {
2407         WLOGFE("FillSessionInfo bundleName_ is null");
2408         return;
2409     }
2410     if (sessionInfo.isSystem_) {
2411         WLOGFD("FillSessionInfo systemScene!");
2412         return;
2413     }
2414     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
2415         sessionInfo.moduleName_);
2416     if (abilityInfo == nullptr) {
2417         WLOGFE("FillSessionInfo abilityInfo is nullptr!");
2418         return;
2419     }
2420     sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
2421     sceneSession->SetSessionInfoTime(GetCurrentTime());
2422     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
2423         sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
2424     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
2425         sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
2426     }
2427     WLOGFI("FillSessionInfo end, removeMissionAfterTerminate: %{public}d excludeFromMissions: %{public}d "
2428            " label:%{public}s iconPath:%{public}s collaboratorType:%{public}s",
2429            abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
2430            abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
2431 }
2432 
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)2433 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
2434     const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
2435 {
2436     AAFwk::Want want;
2437     want.SetElementName("", bundleName, abilityName, moduleName);
2438     std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
2439     if (abilityInfo == nullptr) {
2440         WLOGFE("QueryAbilityInfoFromBMS abilityInfo is nullptr!");
2441         return nullptr;
2442     }
2443     auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
2444         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
2445         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
2446     bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
2447     if (!ret) {
2448         WLOGFE("Get ability info from BMS failed!");
2449         return nullptr;
2450     }
2451     return abilityInfo;
2452 }
2453 
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)2454 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
2455 {
2456     const auto& callingPid = IPCSkeleton::GetCallingRealPid();
2457     auto task = [this, mainWinId, &topWinId, callingPid]() {
2458         const auto& mainSession = GetSceneSession(mainWinId);
2459         if (mainSession == nullptr) {
2460             return WMError::WM_ERROR_INVALID_WINDOW;
2461         }
2462 
2463         if (callingPid != mainSession->GetCallingPid()) {
2464             WLOGFE("Permission denied, not destroy by the same process");
2465             return WMError::WM_ERROR_INVALID_PERMISSION;
2466         }
2467         const auto& subVec = mainSession->GetSubSession();
2468         uint32_t zOrder = mainSession->GetZOrder();
2469         topWinId = mainWinId;
2470         for (const auto& subSession : subVec) {
2471             if (subSession != nullptr && (subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
2472                 subSession->GetSessionState() == SessionState::STATE_ACTIVE) && subSession->GetZOrder() > zOrder) {
2473                 topWinId = subSession->GetPersistentId();
2474                 zOrder = subSession->GetZOrder();
2475                 WLOGFD("[GetTopWin] Current zorder is larger than mainWin, mainId: %{public}d, topWinId: %{public}d, "
2476                     "zOrder: %{public}d", mainWinId, topWinId, zOrder);
2477             }
2478         }
2479         WLOGFD("[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, zOrder: %{public}d",
2480             mainWinId, topWinId, zOrder);
2481         return WMError::WM_OK;
2482     };
2483     return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
2484 }
2485 
UpdateSessionProperty(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)2486 WMError SceneSessionManager::UpdateSessionProperty(const sptr<WindowSessionProperty>& property,
2487     WSPropertyChangeAction action)
2488 {
2489     if (property == nullptr) {
2490         WLOGFE("property is nullptr");
2491         return WMError::WM_ERROR_NULLPTR;
2492     }
2493     if (action == WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE) {
2494         if (!SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
2495             return WMError::WM_ERROR_INVALID_PERMISSION;
2496         }
2497     }
2498 
2499     bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
2500     property->SetSystemCalling(isSystemCalling);
2501     wptr<SceneSessionManager> weak = this;
2502     auto task = [weak, property, action]() -> WMError {
2503         auto weakSession = weak.promote();
2504         if (weakSession == nullptr) {
2505             WLOGFE("the session is nullptr");
2506             return WMError::WM_DO_NOTHING;
2507         }
2508         if (property == nullptr) {
2509             WLOGFE("the property is nullptr");
2510             return WMError::WM_DO_NOTHING;
2511         }
2512         auto sceneSession = weakSession->GetSceneSession(property->GetPersistentId());
2513         if (sceneSession == nullptr) {
2514             WLOGFW("the scene session is nullptr, persistentId: %{public}d", property->GetPersistentId());
2515             return WMError::WM_DO_NOTHING;
2516         }
2517         WLOGD("Id: %{public}d, action: %{public}u", sceneSession->GetPersistentId(), action);
2518         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:UpdateProperty");
2519         return weakSession->HandleUpdateProperty(property, action, sceneSession);
2520     };
2521     return taskScheduler_->PostSyncTask(task, "UpdateProperty");
2522 }
2523 
UpdatePropertyDragEnabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2524 WMError SceneSessionManager::UpdatePropertyDragEnabled(const sptr<WindowSessionProperty>& property,
2525                                                        const sptr<SceneSession>& sceneSession)
2526 {
2527     if (!property->GetSystemCalling()) {
2528         WLOGFE("Update property dragEnabled permission denied!");
2529         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2530     }
2531 
2532     if (sceneSession->GetSessionProperty() != nullptr) {
2533         sceneSession->GetSessionProperty()->SetDragEnabled(property->GetDragEnabled());
2534     }
2535     return WMError::WM_OK;
2536 }
2537 
UpdatePropertyRaiseEnabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2538 WMError SceneSessionManager::UpdatePropertyRaiseEnabled(const sptr<WindowSessionProperty>& property,
2539                                                         const sptr<SceneSession>& sceneSession)
2540 {
2541     if (!property->GetSystemCalling()) {
2542         WLOGFE("Update property raiseEnabled permission denied!");
2543         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2544     }
2545 
2546     if (sceneSession->GetSessionProperty() != nullptr) {
2547         sceneSession->GetSessionProperty()->SetRaiseEnabled(property->GetRaiseEnabled());
2548     }
2549     return WMError::WM_OK;
2550 }
2551 
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2552 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
2553     const sptr<SceneSession>& sceneSession)
2554 {
2555     auto systemBarProperties = property->GetSystemBarProperty();
2556     for (auto iter : systemBarProperties) {
2557         if (iter.first == type) {
2558             sceneSession->SetSystemBarProperty(iter.first, iter.second);
2559             WLOGFD("SetSystemBarProperty: %{public}d, enable: %{public}d",
2560                    static_cast<int32_t>(iter.first), iter.second.enable_);
2561         }
2562     }
2563     NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2564 }
2565 
SetCallingSession(const sptr<SceneSession> & sceneSession,uint32_t newCallingWindowId)2566 void SceneSessionManager::SetCallingSession(const sptr<SceneSession>& sceneSession, uint32_t newCallingWindowId)
2567 {
2568     uint32_t oldCallingWindowId = INVALID_WINDOW_ID;
2569     if (sceneSession && sceneSession->GetSessionProperty()) {
2570         oldCallingWindowId = sceneSession->GetSessionProperty()->GetCallingWindow();
2571     }
2572     if (callingSession_ && oldCallingWindowId == newCallingWindowId) {
2573         WLOGFI("[WMSInput] CallingWindowId not changed, not need to reset callingSession");
2574         return;
2575     }
2576     WLOGFI("[WMSInput] Get callingSesstion by CallingWindowId: %{public}d", newCallingWindowId);
2577     callingSession_ = GetSceneSession(newCallingWindowId);
2578     return;
2579 }
2580 
HandleUpdateProperty(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action,const sptr<SceneSession> & sceneSession)2581 WMError SceneSessionManager::HandleUpdateProperty(const sptr<WindowSessionProperty>& property,
2582     WSPropertyChangeAction action, const sptr<SceneSession>& sceneSession)
2583 {
2584     switch (action) {
2585         case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON: {
2586             sceneSession->SetTurnScreenOn(property->IsTurnScreenOn());
2587             HandleTurnScreenOn(sceneSession);
2588             break;
2589         }
2590         case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON: {
2591             sceneSession->SetKeepScreenOn(property->IsKeepScreenOn());
2592             HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
2593             break;
2594         }
2595         case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE: {
2596             sceneSession->SetFocusable(property->GetFocusable());
2597             NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2598             break;
2599         }
2600         case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE: {
2601             sceneSession->SetTouchable(property->GetTouchable());
2602             NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2603             break;
2604         }
2605         case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS: {
2606             if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2607                 WLOGW("only app main window can set brightness");
2608                 return WMError::WM_OK;
2609             }
2610             // @todo if sceneSession is inactive, return
2611             SetBrightness(sceneSession, property->GetBrightness());
2612             break;
2613         }
2614         case WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION: {
2615             sceneSession->SetRequestedOrientation(property->GetRequestedOrientation());
2616             break;
2617         }
2618         case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: {
2619             bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
2620             sceneSession->SetPrivacyMode(isPrivacyMode);
2621             UpdatePrivateStateAndNotify(sceneSession->GetPersistentId());
2622             break;
2623         }
2624         case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE: {
2625             bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
2626             sceneSession->SetPrivacyMode(isPrivacyMode);
2627             UpdatePrivateStateAndNotify(sceneSession->GetPersistentId());
2628             break;
2629         }
2630         case WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE: {
2631             if (sceneSession->GetSessionProperty() != nullptr) {
2632                 sceneSession->GetSessionProperty()->SetMaximizeMode(property->GetMaximizeMode());
2633             }
2634             break;
2635         }
2636         case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS: {
2637             auto systemBarProperties = property->GetSystemBarProperty();
2638             for (auto iter : systemBarProperties) {
2639                 sceneSession->SetSystemBarProperty(iter.first, iter.second);
2640             }
2641             NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2642             break;
2643         }
2644         case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS: {
2645             HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, property, sceneSession);
2646             break;
2647         }
2648         case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS: {
2649             HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, property, sceneSession);
2650             break;
2651         }
2652         case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS: {
2653             HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, property, sceneSession);
2654             break;
2655         }
2656         case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
2657             SetWindowFlags(sceneSession, property);
2658             NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2659             break;
2660         }
2661         case WSPropertyChangeAction::ACTION_UPDATE_MODE: {
2662             if (sceneSession->GetSessionProperty() != nullptr) {
2663                 sceneSession->GetSessionProperty()->SetWindowMode(property->GetWindowMode());
2664             }
2665             NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2666             break;
2667         }
2668         case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: {
2669             if (sceneSession->GetSessionProperty() != nullptr) {
2670                 sceneSession->GetSessionProperty()->SetAnimationFlag(property->GetAnimationFlag());
2671             }
2672             break;
2673         }
2674         case WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA: {
2675             if (sceneSession->GetSessionProperty() != nullptr) {
2676                 std::vector<Rect> touchHotAreas;
2677                 property->GetTouchHotAreas(touchHotAreas);
2678                 sceneSession->GetSessionProperty()->SetTouchHotAreas(touchHotAreas);
2679             }
2680             break;
2681         }
2682         case WSPropertyChangeAction::ACTION_UPDATE_CALLING_WINDOW: {
2683             if (sceneSession->GetSessionProperty() != nullptr) {
2684                 SetCallingSession(sceneSession, property->GetCallingWindow());
2685                 sceneSession->GetSessionProperty()->SetCallingWindow(property->GetCallingWindow());
2686             }
2687             if (callingWindowIdChangeFunc_ != nullptr) {
2688                 callingWindowIdChangeFunc_(property->GetCallingWindow());
2689             }
2690             break;
2691         }
2692         case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE: {
2693             if (property != nullptr && !property->GetSystemCalling()) {
2694                 WLOGFE("update decor enable permission denied!");
2695                 break;
2696             }
2697             if (sceneSession->GetSessionProperty() != nullptr) {
2698                 sceneSession->GetSessionProperty()->SetDecorEnable(property->IsDecorEnable());
2699             }
2700             break;
2701         }
2702         case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS: {
2703             if (sceneSession->GetSessionProperty() != nullptr) {
2704                 sceneSession->GetSessionProperty()->SetWindowLimits(property->GetWindowLimits());
2705             }
2706             break;
2707         }
2708         case WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED: {
2709             return UpdatePropertyDragEnabled(property, sceneSession);
2710         }
2711         case WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED: {
2712             return UpdatePropertyRaiseEnabled(property, sceneSession);
2713         }
2714         case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS: {
2715             UpdateHideNonSystemFloatingWindows(property, sceneSession);
2716             break;
2717         }
2718         default:
2719             break;
2720     }
2721     return WMError::WM_OK;
2722 }
2723 
UpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2724 void SceneSessionManager::UpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
2725     const sptr<SceneSession>& sceneSession)
2726 {
2727     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2728         WLOGFE("Update property hideNonSystemFloatingWindows permission denied!");
2729         return;
2730     }
2731 
2732     auto propertyOld = sceneSession->GetSessionProperty();
2733     if (propertyOld == nullptr) {
2734         WLOGFI("UpdateHideNonSystemFloatingWindows, session property null");
2735         return;
2736     }
2737 
2738     bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
2739     bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
2740     if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
2741         WLOGFI("property hideNonSystemFloatingWindows not change");
2742         return;
2743     }
2744 
2745     if (IsSessionVisible(sceneSession)) {
2746         if (hideNonSystemFloatingWindowsOld) {
2747             UpdateForceHideState(sceneSession, propertyOld, false);
2748         } else {
2749             UpdateForceHideState(sceneSession, property, true);
2750         }
2751     }
2752     propertyOld->SetHideNonSystemFloatingWindows(hideNonSystemFloatingWindowsNew);
2753 }
2754 
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)2755 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
2756     const sptr<WindowSessionProperty>& property, bool add)
2757 {
2758     if (property == nullptr) {
2759         WLOGFD("property is nullptr");
2760         return;
2761     }
2762     auto persistentId = sceneSession->GetPersistentId();
2763     bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
2764     bool notifyAll = false;
2765     if (add) {
2766         if (property->GetHideNonSystemFloatingWindows()) {
2767             systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
2768             notifyAll = !forceHideFloatOld;
2769         } else if (property->IsFloatingWindowAppType()) {
2770             nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
2771             if (forceHideFloatOld) {
2772                 sceneSession->NotifyForceHideChange(true);
2773             }
2774         }
2775     } else {
2776         if (property->GetHideNonSystemFloatingWindows()) {
2777             systemTopSceneSessionMap_.erase(persistentId);
2778             notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
2779         } else if (property->IsFloatingWindowAppType()) {
2780             nonSystemFloatSceneSessionMap_.erase(persistentId);
2781             if (property->GetForceHide()) {
2782                 sceneSession->NotifyForceHideChange(false);
2783             }
2784         }
2785     }
2786     if (notifyAll) {
2787         bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
2788         for (const auto &item : nonSystemFloatSceneSessionMap_) {
2789             auto forceHideSceneSession = item.second;
2790             auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
2791             if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
2792                 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
2793             }
2794         }
2795     }
2796 }
2797 
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)2798 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
2799 {
2800 #ifdef POWER_MANAGER_ENABLE
2801     auto task = [this, sceneSession]() {
2802         if (sceneSession == nullptr) {
2803             WLOGFE("session is invalid");
2804             return;
2805         }
2806         WLOGFD("Win: %{public}s, is turn on%{public}d",
2807             sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
2808         std::string identity = IPCSkeleton::ResetCallingIdentity();
2809         if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
2810             WLOGI("turn screen on");
2811             PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
2812         }
2813         // set ipc identity to raw
2814         IPCSkeleton::SetCallingIdentity(identity);
2815     };
2816     taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
2817 
2818 #else
2819     WLOGFD("Can not found the sub system of PowerMgr");
2820 #endif
2821 }
2822 
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)2823 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
2824 {
2825 #ifdef POWER_MANAGER_ENABLE
2826     wptr<SceneSession> weakSceneSession(sceneSession);
2827     auto task = [this, weakSceneSession, requireLock]() {
2828         auto scnSession = weakSceneSession.promote();
2829         if (scnSession == nullptr) {
2830             WLOGFE("session is invalid");
2831             return;
2832         }
2833         if (requireLock && scnSession->keepScreenLock_ == nullptr) {
2834             // reset ipc identity
2835             std::string identity = IPCSkeleton::ResetCallingIdentity();
2836             scnSession->keepScreenLock_ =
2837                 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
2838                 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
2839             // set ipc identity to raw
2840             IPCSkeleton::SetCallingIdentity(identity);
2841         }
2842         if (scnSession->keepScreenLock_ == nullptr) {
2843             return;
2844         }
2845         bool shouldLock = requireLock && IsSessionVisible(scnSession);
2846         WLOGI("keep screen on: [%{public}s, %{public}d]", scnSession->GetWindowName().c_str(), shouldLock);
2847         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
2848         ErrCode res;
2849         std::string identity = IPCSkeleton::ResetCallingIdentity();
2850         if (shouldLock) {
2851             res = scnSession->keepScreenLock_->Lock();
2852         } else {
2853             res = scnSession->keepScreenLock_->UnLock();
2854         }
2855         // set ipc identity to raw
2856         IPCSkeleton::SetCallingIdentity(identity);
2857         if (res != ERR_OK) {
2858             WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
2859                 requireLock, res);
2860         }
2861     };
2862     taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
2863 #else
2864     WLOGFD("Can not found the sub system of PowerMgr");
2865 #endif
2866 }
2867 
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)2868 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
2869 {
2870     if (!sceneSession->IsSessionValid()) {
2871         return WSError::WS_ERROR_INVALID_SESSION;
2872     }
2873     if (brightness == sceneSession->GetBrightness()) {
2874         WLOGFD("Session brightness do not change: [%{public}f]", brightness);
2875         return WSError::WS_DO_NOTHING;
2876     }
2877     sceneSession->SetBrightness(brightness);
2878 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
2879     if (GetDisplayBrightness() != brightness) {
2880         if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
2881             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
2882             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
2883         } else {
2884             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
2885                 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
2886             SetDisplayBrightness(brightness);
2887         }
2888     }
2889 #else
2890     WLOGFD("Can not found the sub system of DisplayPowerMgr");
2891 #endif
2892     brightnessSessionId_ = sceneSession->GetPersistentId();
2893     return WSError::WS_OK;
2894 }
2895 
UpdateBrightness(int32_t persistentId)2896 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
2897 {
2898     auto sceneSession = GetSceneSession(persistentId);
2899     if (sceneSession == nullptr) {
2900         WLOGFE("session is invalid");
2901         return WSError::WS_ERROR_NULLPTR;
2902     }
2903     if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
2904             sceneSession->GetSessionInfo().isSystem_)) {
2905         WLOGW("only app main window can set brightness");
2906         return WSError::WS_DO_NOTHING;
2907     }
2908     auto brightness = sceneSession->GetBrightness();
2909     WLOGI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
2910     if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
2911         if (GetDisplayBrightness() != brightness) {
2912             WLOGI("adjust brightness with default value");
2913             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
2914             SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
2915         }
2916         brightnessSessionId_ = INVALID_WINDOW_ID;
2917     } else {
2918         if (GetDisplayBrightness() != brightness) {
2919             WLOGI("adjust brightness with value");
2920             DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
2921                 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
2922             SetDisplayBrightness(brightness);
2923         }
2924         brightnessSessionId_ = sceneSession->GetPersistentId();
2925     }
2926     return WSError::WS_OK;
2927 }
2928 
GetCurrentUserId() const2929 int32_t SceneSessionManager::GetCurrentUserId() const
2930 {
2931     return currentUserId_;
2932 }
2933 
SetDisplayBrightness(float brightness)2934 void SceneSessionManager::SetDisplayBrightness(float brightness)
2935 {
2936     displayBrightness_ = brightness;
2937 }
2938 
GetDisplayBrightness() const2939 float SceneSessionManager::GetDisplayBrightness() const
2940 {
2941     return displayBrightness_;
2942 }
2943 
SetGestureNavigaionEnabled(bool enable)2944 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
2945 {
2946     if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2947         WLOGFE("SetGestureNavigationEnabled permission denied!");
2948         return WMError::WM_ERROR_NOT_SYSTEM_APP;
2949     }
2950     WLOGFD("SetGestureNavigationEnabled, enable: %{public}d", enable);
2951     gestureNavigationEnabled_ = enable;
2952     auto task = [this, enable]() {
2953         if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
2954             WLOGFE("callback func is null");
2955             return WMError::WM_DO_NOTHING;
2956         }
2957         if (gestureNavigationEnabledChangeFunc_) {
2958             gestureNavigationEnabledChangeFunc_(enable);
2959         }
2960         if (statusBarEnabledChangeFunc_) {
2961             statusBarEnabledChangeFunc_(enable);
2962         }
2963         return WMError::WM_OK;
2964     };
2965     return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
2966 }
2967 
SetFocusedSession(int32_t persistentId)2968 WSError SceneSessionManager::SetFocusedSession(int32_t persistentId)
2969 {
2970     if (focusedSessionId_ == persistentId) {
2971         WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
2972         return WSError::WS_DO_NOTHING;
2973     }
2974     lastFocusedSessionId_ = focusedSessionId_;
2975     focusedSessionId_ = persistentId;
2976     return WSError::WS_OK;
2977 }
2978 
GetFocusedSession() const2979 int32_t SceneSessionManager::GetFocusedSession() const
2980 {
2981     return focusedSessionId_;
2982 }
2983 
GetFocusWindowInfo(FocusChangeInfo & focusInfo)2984 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
2985 {
2986     auto sceneSession = GetSceneSession(focusedSessionId_);
2987     if (sceneSession) {
2988         WLOGFD("Get focus session info success");
2989         focusInfo.windowId_ = sceneSession->GetWindowId();
2990         focusInfo.displayId_ = static_cast<DisplayId>(0);
2991         focusInfo.pid_ = sceneSession->GetCallingPid();
2992         focusInfo.uid_ = sceneSession->GetCallingUid();
2993         focusInfo.windowType_ = sceneSession->GetWindowType();
2994         focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
2995     }
2996     return;
2997 }
2998 
IsValidDigitString(const std::string & windowIdStr)2999 static bool IsValidDigitString(const std::string& windowIdStr)
3000 {
3001     if (windowIdStr.empty()) {
3002         return false;
3003     }
3004     for (char ch : windowIdStr) {
3005         if ((ch >= '0' && ch <= '9')) {
3006             continue;
3007         }
3008         WLOGFE("invalid window id");
3009         return false;
3010     }
3011     return true;
3012 }
3013 
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)3014 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
3015 {
3016     if (sceneSession == nullptr) {
3017         WLOGFE("session is nullptr");
3018         return;
3019     }
3020     NotifySessionExceptionFunc sessionExceptionFunc = [this](const SessionInfo& info, bool needRemoveSession = false) {
3021         auto task = [this, info]() {
3022             auto scnSession = GetSceneSession(info.persistentId_);
3023             if (scnSession == nullptr) {
3024                 WLOGFW("[WMSLife]NotifySessionExceptionFunc, Not found session, id: %{public}d", info.persistentId_);
3025                 return;
3026             }
3027             if (listenerController_ == nullptr) {
3028                 WLOGFW("[WMSLife]NotifySessionExceptionFunc, listenerController_ is nullptr");
3029                 return;
3030             }
3031             if (scnSession->GetSessionInfo().isSystem_) {
3032                 WLOGFW("[WMSLife]NotifySessionExceptionFunc, id: %{public}d is system", scnSession->GetPersistentId());
3033                 return;
3034             }
3035             WLOGFI("[WMSLife]NotifySessionExceptionFunc, errorCode: %{public}d, id: %{public}d", info.errorCode,
3036                    info.persistentId_);
3037             if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
3038                 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
3039                 WLOGFD("[WMSLife]NotifySessionClosed when ability load timeout or foreground timeout, id: %{public}d",
3040                        info.persistentId_);
3041                 listenerController_->NotifySessionClosed(info.persistentId_);
3042             }
3043         };
3044         taskScheduler_->PostVoidSyncTask(task, "sessionException");
3045     };
3046     sceneSession->SetSessionExceptionListener(sessionExceptionFunc, false);
3047     WLOGFD("[WMSLife]RegisterSessionExceptionFunc success, id: %{public}d", sceneSession->GetPersistentId());
3048 }
3049 
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)3050 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
3051 {
3052     if (sceneSession == nullptr) {
3053         WLOGFE("session is nullptr");
3054         return;
3055     }
3056     NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
3057         auto task = [this, persistentId]() {
3058             auto scnSession = GetSceneSession(persistentId);
3059             if (scnSession == nullptr) {
3060                 WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
3061                 return;
3062             }
3063             if (scnSession->GetSessionInfo().isSystem_) {
3064                 WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", scnSession->GetPersistentId());
3065                 return;
3066             }
3067             auto abilityInfoPtr = scnSession->GetSessionInfo().abilityInfo;
3068             if (abilityInfoPtr == nullptr) {
3069                 WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
3070                 return;
3071             }
3072             if (listenerController_ == nullptr) {
3073                 WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
3074                 return;
3075             }
3076             if (!(abilityInfoPtr->excludeFromMissions)) {
3077                 listenerController_->NotifySessionSnapshotChanged(persistentId);
3078             }
3079         };
3080         taskScheduler_->PostVoidSyncTask(task, "sessionSnapshot");
3081     };
3082     sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
3083     WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
3084 }
3085 
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)3086 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
3087 {
3088     if (scnSession == nullptr) {
3089         WLOGFW("NotifySessionForCallback, scnSession is nullptr");
3090         return;
3091     }
3092     if (scnSession->GetSessionInfo().isSystem_) {
3093         WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
3094         return;
3095     }
3096     WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
3097            static_cast<uint32_t>(needRemoveSession));
3098     if (scnSession->GetSessionInfo().appIndex_ != 0) {
3099         WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
3100                scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
3101         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
3102         return;
3103     }
3104     if (needRemoveSession) {
3105         WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
3106         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
3107         return;
3108     }
3109     if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
3110         WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
3111     } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
3112                (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
3113         WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
3114             scnSession->GetPersistentId());
3115         listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
3116         return;
3117     }
3118     WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
3119     listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
3120 }
3121 
3122 
NotifyWindowInfoChangeFromSession(int32_t persistentId)3123 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
3124 {
3125     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
3126     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
3127     if (sceneSession == nullptr) {
3128         WLOGFE("sceneSession nullptr");
3129         return;
3130     }
3131 
3132     SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
3133 }
3134 
IsSessionVisible(const sptr<SceneSession> & session)3135 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
3136 {
3137     if (session == nullptr) {
3138         return false;
3139     }
3140     const auto& state = session->GetSessionState();
3141     if (WindowHelper::IsSubWindow(session->GetWindowType())) {
3142         const auto& parentSceneSession = GetSceneSession(session->GetParentPersistentId());
3143         if (parentSceneSession == nullptr) {
3144             WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
3145             return false;
3146         }
3147         const auto& parentState = parentSceneSession->GetSessionState();
3148         if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
3149             if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
3150                 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
3151                 return false;
3152             }
3153             WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
3154             return true;
3155         }
3156         WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
3157         return false;
3158     }
3159 
3160     if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
3161         WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
3162         return true;
3163     }
3164     WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
3165     return false;
3166 }
3167 
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)3168 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
3169 {
3170     if (session == nullptr) {
3171         return;
3172     }
3173     int32_t zOrder = IsSessionVisible(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
3174     WSRect rect = session->GetSessionRect();
3175     std::string sName;
3176     if (session->GetSessionInfo().isSystem_) {
3177         sName = session->GetSessionInfo().abilityName_;
3178     } else {
3179         sName = session->GetWindowName();
3180     }
3181     uint32_t flag = 0;
3182     uint64_t displayId = INVALID_SCREEN_ID;
3183     if (session->GetSessionProperty()) {
3184         flag = session->GetSessionProperty()->GetWindowFlags();
3185         displayId = session->GetSessionProperty()->GetDisplayId();
3186     }
3187     uint32_t orientation = 0;
3188     const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
3189         sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
3190     // std::setw is used to set the output width and different width values are set to keep the format aligned.
3191     oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
3192         << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
3193         << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
3194         << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
3195         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
3196         << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
3197         << std::left << std::setw(VALUE_MAX_WIDTH) << flag
3198         << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
3199         << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
3200         << "[ "
3201         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
3202         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
3203         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
3204         << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
3205         << "]"
3206         << " [ "
3207         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
3208         << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
3209         << "]"
3210         << " [ "
3211         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
3212         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
3213         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
3214         << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
3215         << "]"
3216         << std::endl;
3217 }
3218 
DumpAllAppSessionInfo(std::ostringstream & oss,const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap)3219 void SceneSessionManager::DumpAllAppSessionInfo(std::ostringstream& oss,
3220     const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap)
3221 {
3222     oss << std::endl << "Current mission lists:" << std::endl;
3223     oss << " MissionList Type #NORMAL" << std::endl;
3224     for (const auto& elem : sceneSessionMap) {
3225         auto curSession = elem.second;
3226         if (curSession == nullptr) {
3227             WLOGFW("curSession is nullptr");
3228             continue;
3229         }
3230         if (curSession->GetSessionInfo().isSystem_ ||
3231             curSession->GetWindowType() < WindowType::APP_MAIN_WINDOW_BASE ||
3232             curSession->GetWindowType() >= WindowType::APP_MAIN_WINDOW_END) {
3233             WLOGFW("No need to dump, id: %{public}d, isSystem: %{public}d, windowType: %{public}d",
3234                 curSession->GetPersistentId(), curSession->GetSessionInfo().isSystem_, curSession->GetWindowType());
3235             continue;
3236         }
3237 
3238         const auto& sessionInfo = curSession->GetSessionInfo();
3239         std::string isActive = curSession->IsActive() ? "FOREGROUND" : "BACKGROUND";
3240         oss << "    Mission ID #" << curSession->GetPersistentId() << "  mission name #" << "[#"
3241             << sessionInfo.bundleName_ << ":" << sessionInfo.moduleName_ << ":" << sessionInfo.abilityName_
3242             << "]" << "    lockedState #0" << std::endl;
3243         oss << "    app name [" << sessionInfo.bundleName_ << "]" << std::endl;
3244         oss << "    main name [" << sessionInfo.abilityName_ << "]" << std::endl;
3245         oss << "    bundle name [" << sessionInfo.bundleName_ << "]" << std::endl;
3246         oss << "    ability type [PAGE]" << std::endl;
3247         oss << "    state #" << isActive.c_str() << std::endl;
3248         oss << "    app state #" << isActive.c_str() << std::endl;
3249         oss << "    callee connections:" << std::endl;
3250     }
3251 }
3252 
GetAllSessionDumpInfo(std::string & dumpInfo)3253 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
3254 {
3255     int32_t screenGroupId = 0;
3256     std::ostringstream oss;
3257     oss << "-------------------------------------ScreenGroup " << screenGroupId
3258         << "-------------------------------------" << std::endl;
3259     oss << "WindowName           DisplayId Pid     WinId Type Mode Flag ZOrd Orientation [ x    y    w    h    ]"
3260         << " [ OffsetX OffsetY ] [ ScaleX  ScaleY  PivotX  PivotY  ]"
3261         << std::endl;
3262 
3263     std::vector<sptr<SceneSession>> allSession;
3264     std::vector<sptr<SceneSession>> backgroundSession;
3265     std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
3266     {
3267         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3268         sceneSessionMapCopy = sceneSessionMap_;
3269     }
3270     for (const auto& elem : sceneSessionMapCopy) {
3271         auto curSession = elem.second;
3272         if (curSession == nullptr) {
3273             continue;
3274         }
3275         if (IsSessionVisible(curSession)) {
3276             allSession.push_back(curSession);
3277         } else {
3278             backgroundSession.push_back(curSession);
3279         }
3280     }
3281     allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
3282     uint32_t count = 0;
3283     for (const auto& session : allSession) {
3284         if (session == nullptr) {
3285             continue;
3286         }
3287         if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
3288             oss << "---------------------------------------------------------------------------------------"
3289                 << std::endl;
3290         }
3291         DumpSessionInfo(session, oss);
3292         count++;
3293     }
3294     oss << "Focus window: " << GetFocusedSession() << std::endl;
3295     oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
3296     DumpAllAppSessionInfo(oss, sceneSessionMapCopy);
3297     dumpInfo.append(oss.str());
3298     return WSError::WS_OK;
3299 }
3300 
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)3301 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
3302 {
3303     dumpRootSceneFunc_ = func;
3304 }
3305 
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)3306 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
3307     const std::vector<std::string>& params, std::string& dumpInfo)
3308 {
3309     std::vector<std::string> resetParams;
3310     resetParams.assign(params.begin() + 2, params.end()); // 2: params num
3311     if (resetParams.empty()) {
3312         WLOGI("do not dump ui info");
3313         return;
3314     }
3315 
3316     if (!session->GetSessionInfo().isSystem_) {
3317         WLOGFI("Dump normal session, not system");
3318         dumpInfoFuture_.ResetLock({});
3319         session->DumpSessionElementInfo(resetParams);
3320         std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
3321         for (auto& info: infos) {
3322             dumpInfo.append(info).append("\n");
3323         }
3324     } else {
3325         WLOGFI("Dump system session");
3326         std::vector<std::string> infos;
3327         dumpRootSceneFunc_(resetParams, infos);
3328         for (auto& info: infos) {
3329             dumpInfo.append(info).append("\n");
3330         }
3331     }
3332 }
3333 
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)3334 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
3335     const std::string& strId)
3336 {
3337     uint64_t persistentId = std::stoull(strId);
3338     auto session = GetSceneSession(persistentId);
3339     if (session == nullptr) {
3340         return WSError::WS_ERROR_INVALID_PARAM;
3341     }
3342 
3343     WSRect rect = session->GetSessionRect();
3344     std::string isVisible = session->GetVisible() ? "true" : "false";
3345     std::string Focusable = session->GetFocusable() ? "true" : "false";
3346     std::string DecoStatus = session->GetSessionProperty()->IsDecorEnable() ? "true" : "false";
3347     bool PrivacyMode = session->GetSessionProperty()->GetSystemPrivacyMode() ||
3348         session->GetSessionProperty()->GetPrivacyMode();
3349     std::string isPrivacyMode = PrivacyMode ? "true" : "false";
3350     bool isFirstFrameAvailable = true;
3351     std::ostringstream oss;
3352     oss << "WindowName: " << session->GetWindowName()  << std::endl;
3353     oss << "DisplayId: " << 0 << std::endl;
3354     oss << "WinId: " << session->GetPersistentId() << std::endl;
3355     oss << "Pid: " << session->GetCallingPid() << std::endl;
3356     oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
3357     oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
3358     oss << "Flag: " << session->GetSessionProperty()->GetWindowFlags() << std::endl;
3359     oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
3360     oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
3361     oss << "IsVisible: " << isVisible << std::endl;
3362     oss << "Focusable: "  << Focusable << std::endl;
3363     oss << "DecoStatus: "  << DecoStatus << std::endl;
3364     oss << "isPrivacyMode: "  << isPrivacyMode << std::endl;
3365     oss << "WindowRect: " << "[ "
3366         << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
3367         << " ]" << std::endl;
3368     oss << "Offset: " << "[ "
3369         << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
3370     oss << "Scale: " << "[ "
3371         << session->GetScaleX() << ", " << session->GetScaleY() << ", "
3372         << session->GetPivotX() << ", " << session->GetPivotY()
3373         << " ]" << std::endl;
3374     dumpInfo.append(oss.str());
3375 
3376     DumpSessionElementInfo(session, params, dumpInfo);
3377     return WSError::WS_OK;
3378 }
3379 
NotifyDumpInfoResult(const std::vector<std::string> & info)3380 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
3381 {
3382     dumpInfoFuture_.SetValue(info);
3383     WLOGFD("NotifyDumpInfoResult");
3384 }
3385 
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)3386 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
3387 {
3388     if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
3389         WLOGFE("GetSessionDumpInfo permission denied!");
3390         return WSError::WS_ERROR_INVALID_PERMISSION;
3391     }
3392     auto task = [this, params, &dumpInfo]() {
3393         if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
3394             return GetAllSessionDumpInfo(dumpInfo);
3395         }
3396         if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
3397             return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
3398         }
3399         return WSError::WS_ERROR_INVALID_OPERATION;
3400     };
3401     return taskScheduler_->PostSyncTask(task);
3402 }
3403 
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)3404 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
3405 {
3406     // notify RS
3407     WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
3408         " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
3409         sceneSession->GetSessionProperty()->GetWindowName().c_str(),
3410         sceneSession->GetSessionInfo().bundleName_.c_str(),
3411         sceneSession->GetSessionInfo().abilityName_.c_str(),
3412         sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
3413     uint64_t focusNodeId = 0; // 0 means invalid
3414     if (sceneSession->GetSurfaceNode() == nullptr) {
3415         WLOGFW("focused window surfaceNode is null");
3416     } else {
3417         focusNodeId = sceneSession->GetSurfaceNode()->GetId();
3418     }
3419     FocusAppInfo appInfo = {
3420         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
3421         sceneSession->GetSessionInfo().bundleName_,
3422         sceneSession->GetSessionInfo().abilityName_, focusNodeId};
3423     RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
3424 }
3425 
3426 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)3427 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
3428 {
3429     std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
3430     {
3431         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3432         for (auto& iter : sceneSessionMap_) {
3433             ret.push_back(iter);
3434         }
3435     }
3436     std::sort(ret.begin(), ret.end(), cmp);
3437     return ret;
3438 }
3439 
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)3440 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
3441 {
3442     if (isFromTopToBottom) {
3443         TraverseSessionTreeFromTopToBottom(func);
3444     } else {
3445         TraverseSessionTreeFromBottomToTop(func);
3446     }
3447     return;
3448 }
3449 
TraverseSessionTreeFromTopToBottom(TraverseFunc func)3450 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
3451 {
3452     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
3453         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
3454         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
3455         return lhsZOrder < rhsZOrder;
3456     };
3457     auto sceneSessionVector = GetSceneSessionVector(cmp);
3458 
3459     for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
3460         auto session = iter->second;
3461         if (session == nullptr) {
3462             WLOGFE("session is nullptr");
3463             continue;
3464         }
3465         if (func(session)) {
3466             return;
3467         }
3468     }
3469     return;
3470 }
3471 
TraverseSessionTreeFromBottomToTop(TraverseFunc func)3472 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
3473 {
3474     // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3475     CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
3476         uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
3477         uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
3478         return lhsZOrder < rhsZOrder;
3479     };
3480     auto sceneSessionVector = GetSceneSessionVector(cmp);
3481     // std::map<int32_t, sptr<SceneSession>>::iterator iter;
3482     for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
3483         auto session = iter->second;
3484         if (session == nullptr) {
3485             WLOGFE("session is nullptr");
3486             continue;
3487         }
3488         if (func(session)) {
3489             return;
3490         }
3491     }
3492     return;
3493 }
3494 
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground)3495 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground)
3496 {
3497     auto task = [this, persistentId, isFocused, byForeground]() {
3498         if (isFocused) {
3499             RequestSessionFocus(persistentId, byForeground);
3500         } else {
3501             RequestSessionUnfocus(persistentId);
3502         }
3503     };
3504     taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
3505     return WMError::WM_OK;
3506 }
3507 
RequestAllAppSessionUnfocus()3508 void SceneSessionManager::RequestAllAppSessionUnfocus()
3509 {
3510     auto task = [this]() {
3511         RequestAllAppSessionUnfocusInner();
3512     };
3513     taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
3514     return;
3515 }
3516 
3517 /**
3518  * request focus and ignore its state
3519  * only used when app main window start before foreground
3520 */
RequestSessionFocusImmediately(int32_t persistentId)3521 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
3522 {
3523     WLOGFI("[WMSFocus]RequestSessionFocusImmediately, id: %{public}d", persistentId);
3524     // base block
3525     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
3526     if (basicCheckRet != WSError::WS_OK) {
3527         return basicCheckRet;
3528     }
3529     auto sceneSession = GetSceneSession(persistentId);
3530     if (sceneSession == nullptr) {
3531         WLOGFE("[WMSComm]session is nullptr");
3532         return WSError::WS_ERROR_INVALID_SESSION;
3533     }
3534     if (!sceneSession->GetFocusable()) {
3535         WLOGFD("[WMSFocus]session is not focusable!");
3536         return WSError::WS_DO_NOTHING;
3537     }
3538     // specific block
3539     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true);
3540     if (specificCheckRet != WSError::WS_OK) {
3541         return specificCheckRet;
3542     }
3543 
3544     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3545     if (!IsSessionVisible(sceneSession)) {
3546         needBlockNotifyFocusStatusUntilForeground_ = true;
3547     }
3548     ShiftFocus(sceneSession);
3549     return WSError::WS_OK;
3550 }
3551 
RequestSessionFocus(int32_t persistentId,bool byForeground)3552 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground)
3553 {
3554     WLOGFI("[WMSFocus]RequestSessionFocus, id: %{public}d, by foreground: %{public}d", persistentId, byForeground);
3555     WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
3556     if (basicCheckRet != WSError::WS_OK) {
3557         return basicCheckRet;
3558     }
3559     auto sceneSession = GetSceneSession(persistentId);
3560     if (sceneSession == nullptr) {
3561         WLOGFE("[WMSComm]session is nullptr");
3562         return WSError::WS_ERROR_INVALID_SESSION;
3563     }
3564     if (!sceneSession->GetFocusable() || !IsSessionVisible(sceneSession)) {
3565         WLOGFD("[WMSFocus]session is not focusable or not visible!");
3566         return WSError::WS_DO_NOTHING;
3567     }
3568     // subwindow/dialog state block
3569     if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3570         sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
3571         GetSceneSession(sceneSession->GetParentPersistentId()) &&
3572         !IsSessionVisible(GetSceneSession(sceneSession->GetParentPersistentId()))) {
3573             WLOGFD("[WMSFocus]parent session id: %{public}d is not visible!", sceneSession->GetParentPersistentId());
3574             return WSError::WS_DO_NOTHING;
3575     }
3576     // specific block
3577     WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground);
3578     if (specificCheckRet != WSError::WS_OK) {
3579         return specificCheckRet;
3580     }
3581 
3582     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3583     needBlockNotifyFocusStatusUntilForeground_ = false;
3584     ShiftFocus(sceneSession);
3585     return WSError::WS_OK;
3586 }
3587 
RequestSessionUnfocus(int32_t persistentId)3588 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId)
3589 {
3590     WLOGFI("[WMSFocus]RequestSessionUnfocus, id: %{public}d", persistentId);
3591     if (persistentId == INVALID_SESSION_ID) {
3592         WLOGFE("id is invalid");
3593         return WSError::WS_ERROR_INVALID_SESSION;
3594     }
3595     auto focusedSession = GetSceneSession(focusedSessionId_);
3596     if (persistentId != focusedSessionId_ &&
3597         !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
3598         WLOGFD("[WMSFocus]unfocused id cannot request unfocus!");
3599         return WSError::WS_DO_NOTHING;
3600     }
3601     // if pop menu created by desktop request unfocus, back to desktop
3602     auto lastSession = GetSceneSession(lastFocusedSessionId_);
3603     if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
3604         lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
3605         RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
3606             WLOGFD("[WMSFocus]focus is back to desktop");
3607             return WSError::WS_OK;
3608     }
3609     auto nextSession = GetNextFocusableSession(persistentId);
3610 
3611     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3612     needBlockNotifyFocusStatusUntilForeground_ = false;
3613     return ShiftFocus(nextSession);
3614 }
3615 
RequestAllAppSessionUnfocusInner()3616 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
3617 {
3618     WLOGFI("[WMSFocus]RequestAllAppSessionUnfocusInner");
3619     auto focusedSession = GetSceneSession(focusedSessionId_);
3620     if (!focusedSession) {
3621         WLOGFE("[WMSFocus]focused session is null");
3622         return WSError::WS_DO_NOTHING;
3623     }
3624     if (!focusedSession->IsAppSession()) {
3625         WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
3626         return WSError::WS_DO_NOTHING;
3627     }
3628     auto nextSession = GetTopFocusableNonAppSession();
3629 
3630     needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3631     needBlockNotifyFocusStatusUntilForeground_ = false;
3632     return ShiftFocus(nextSession);
3633 }
3634 
RequestFocusBasicCheck(int32_t persistentId)3635 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
3636 {
3637     // basic focus rule
3638     if (persistentId == INVALID_SESSION_ID) {
3639         WLOGFE("[WMSFocus]id is invalid!");
3640         return WSError::WS_ERROR_INVALID_SESSION;
3641     }
3642     if (persistentId == focusedSessionId_) {
3643         WLOGFD("[WMSFocus]request id has been focused!");
3644         return WSError::WS_DO_NOTHING;
3645     }
3646     return WSError::WS_OK;
3647 }
3648 
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground)3649 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground)
3650 {
3651     int32_t persistentId = sceneSession->GetPersistentId();
3652     // dialog get focus
3653     if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
3654         SessionHelper::IsSubWindow(sceneSession->GetWindowType())) &&
3655         ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK) {
3656             WLOGFD("[WMSFocus]dialog is focused");
3657             return WSError::WS_DO_NOTHING;
3658     }
3659     // blocking-type session will block lower zOrder request focus
3660     auto focusedSession = GetSceneSession(focusedSessionId_);
3661     if (focusedSession) {
3662         bool isBlockingType = focusedSession->IsAppSession() ||
3663             (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
3664         if (byForeground && isBlockingType && sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
3665             WLOGFD("[WMSFocus]session %{public}d is lower than focused session %{public}d",
3666                 persistentId, focusedSessionId_);
3667             return WSError::WS_DO_NOTHING;
3668         }
3669         // temp check
3670         if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
3671             sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
3672                 WLOGFD("[WMSFocus]Lower session %{public}d cannot request focus from keyguard!", persistentId);
3673                 return WSError::WS_DO_NOTHING;
3674         }
3675     }
3676     return WSError::WS_OK;
3677 }
3678 
GetNextFocusableSession(int32_t persistentId)3679 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
3680 {
3681     WLOGFD("[WMSFocus]GetNextFocusableSession, id: %{public}d", persistentId);
3682     bool previousFocusedSessionFound = false;
3683     sptr<SceneSession> ret = nullptr;
3684     auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
3685         if (session == nullptr) {
3686             return false;
3687         }
3688         bool parentVisible = true;
3689         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
3690             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
3691             GetSceneSession(session->GetParentPersistentId()) &&
3692             !IsSessionVisible(GetSceneSession(session->GetParentPersistentId()))) {
3693                 parentVisible = false;
3694         }
3695         if (previousFocusedSessionFound && session->GetFocusable() && IsSessionVisible(session) && parentVisible) {
3696             ret = session;
3697             return true;
3698         }
3699         if (session->GetPersistentId() == persistentId) {
3700             previousFocusedSessionFound = true;
3701         }
3702         return false;
3703     };
3704     TraverseSessionTree(func, true);
3705     return ret;
3706 }
3707 
GetTopFocusableNonAppSession()3708 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
3709 {
3710     WLOGFD("[WMSFocus]GetTopFocusableNonAppSession.");
3711     sptr<SceneSession> ret = nullptr;
3712     auto func = [this, &ret](sptr<SceneSession> session) {
3713         if (session == nullptr) {
3714             return false;
3715         }
3716         if (session->IsAppSession()) {
3717             return true;
3718         }
3719         if (session->GetFocusable() && IsSessionVisible(session)) {
3720             ret = session;
3721         }
3722         return false;
3723     };
3724     TraverseSessionTree(func, false);
3725     return ret;
3726 }
3727 
SetShiftFocusListener(const ProcessShiftFocusFunc & func)3728 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
3729 {
3730     WLOGFD("[WMSFocus]SetShiftFocusListener");
3731     shiftFocusFunc_ = func;
3732 }
3733 
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)3734 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
3735 {
3736     WLOGFD("[WMSFocus]SetSCBFocusedListener");
3737     notifySCBAfterFocusedFunc_ = func;
3738 }
3739 
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)3740 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
3741 {
3742     WLOGFD("[WMSFocus]SetSCBUnfocusedListener");
3743     notifySCBAfterUnfocusedFunc_ = func;
3744 }
3745 
SetShowPiPMainWindowListener(const ProcessShowPiPMainWindowFunc & func)3746 void SceneSessionManager::SetShowPiPMainWindowListener(const ProcessShowPiPMainWindowFunc& func)
3747 {
3748     WLOGFD("SetShowPiPMainWindowListener");
3749     showPiPMainWindowFunc_ = func;
3750 }
3751 
SetCallingWindowIdChangeListenser(const ProcessCallingWindowIdChangeFunc & func)3752 void SceneSessionManager::SetCallingWindowIdChangeListenser(const ProcessCallingWindowIdChangeFunc& func)
3753 {
3754     WLOGFD("SetCallingWindowIdChangeListenser");
3755     callingWindowIdChangeFunc_ = func;
3756 }
3757 
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)3758 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
3759 {
3760     WLOGFD("SetStartUIAbilityErrorListener");
3761     startUIAbilityErrorFunc_ = func;
3762 }
3763 
ShiftFocus(sptr<SceneSession> & nextSession)3764 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession)
3765 {
3766     // unfocus
3767     int32_t focusedId = focusedSessionId_;
3768     auto focusedSession = GetSceneSession(focusedSessionId_);
3769     UpdateFocusStatus(focusedSession, false);
3770     // focus
3771     int32_t nextId = INVALID_SESSION_ID;
3772     if (nextSession == nullptr) {
3773         std::string sessionLog(GetAllSessionFocusInfo());
3774         WLOGFW("[WMSFocus]ShiftFocus to nullptr! id: %{public}d, info: %{public}s", focusedSessionId_, sessionLog.c_str());
3775     } else {
3776         nextId = nextSession->GetPersistentId();
3777     }
3778     UpdateFocusStatus(nextSession, true);
3779     bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
3780     bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
3781     if (!scbPrevFocus && scbCurrFocus) {
3782         if (notifySCBAfterFocusedFunc_ != nullptr) {
3783             notifySCBAfterFocusedFunc_();
3784         }
3785     } else if (scbPrevFocus && !scbCurrFocus) {
3786         if (notifySCBAfterUnfocusedFunc_ != nullptr) {
3787             notifySCBAfterUnfocusedFunc_();
3788         }
3789     }
3790     WLOGFI("[WMSFocus]ShiftFocus, focusedId: %{public}d, nextId: %{public}d", focusedId, nextId);
3791     return WSError::WS_OK;
3792 }
3793 
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)3794 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
3795 {
3796     if (sceneSession == nullptr) {
3797         if (isFocused) {
3798             SetFocusedSession(INVALID_SESSION_ID);
3799         }
3800         return;
3801     }
3802     WLOGFI("[WMSFocus]UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
3803         sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
3804     // set focused
3805     if (isFocused) {
3806         SetFocusedSession(sceneSession->GetPersistentId());
3807     }
3808     sceneSession->UpdateFocus(isFocused);
3809     if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
3810         NotifyFocusStatus(sceneSession, isFocused);
3811     }
3812 }
3813 
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)3814 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
3815 {
3816     if (sceneSession == nullptr) {
3817         WLOGFE("[WMSComm]session is nullptr");
3818         return;
3819     }
3820     int32_t persistentId = sceneSession->GetPersistentId();
3821 
3822     WLOGFI("[WMSFocus]NotifyFocusStatus, name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
3823         sceneSession->GetSessionInfo().bundleName_.c_str(),
3824         sceneSession->GetSessionInfo().abilityName_.c_str(),
3825         sceneSession->GetWindowNameAllType().c_str(),
3826         sceneSession->GetPersistentId(), isFocused);
3827     if (isFocused) {
3828         if (IsSessionVisible(sceneSession)) {
3829             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
3830         }
3831         UpdateBrightness(focusedSessionId_);
3832         FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
3833         if (shiftFocusFunc_ != nullptr) {
3834             shiftFocusFunc_(persistentId);
3835         }
3836     }
3837     // notify window manager
3838     sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
3839         sceneSession->GetWindowId(),
3840         static_cast<DisplayId>(0),
3841         sceneSession->GetCallingPid(),
3842         sceneSession->GetCallingUid(),
3843         sceneSession->GetWindowType(),
3844         sceneSession->GetAbilityToken()
3845     );
3846 #ifdef EFFICIENCY_MANAGER_ENABLE
3847         SuspendManager::SuspendManagerClient::GetInstance().ThawOneApplication(focusChangeInfo->uid_,
3848             "", "THAW_BY_FOCUS_CHANGED");
3849 #endif // EFFICIENCY_MANAGER_ENABLE
3850     SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
3851     WSError res = WSError::WS_OK;
3852     res = sceneSession->NotifyFocusStatus(isFocused);
3853     std::string sName = "FoucusWindow:";
3854     if (sceneSession->GetSessionInfo().isSystem_) {
3855         sName += sceneSession->GetSessionInfo().abilityName_;
3856     } else {
3857         sName += sceneSession->GetWindowName();
3858     }
3859     if (isFocused) {
3860         StartAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
3861     } else {
3862         FinishAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
3863     }
3864     if (res != WSError::WS_OK) {
3865         return;
3866     }
3867     // notify listenerController
3868     if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
3869         if (isFocused) {
3870             WLOGFD("[WMSFocus]NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
3871             listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
3872         } else {
3873             WLOGFD("[WMSFocus]NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
3874             listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
3875         }
3876     }
3877     return;
3878 }
3879 
GetAllSessionFocusInfo()3880 std::string SceneSessionManager::GetAllSessionFocusInfo()
3881 {
3882     std::ostringstream os;
3883     auto func = [&os](sptr<SceneSession> session) {
3884         if (session == nullptr) {
3885             WLOGE("sceneSession is nullptr");
3886             return false;
3887         }
3888         os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
3889            " ,focusable: "<< session->GetFocusable() << ";";
3890         return false;
3891     };
3892     TraverseSessionTree(func, true);
3893     return os.str();
3894 }
3895 
UpdateFocus(int32_t persistentId,bool isFocused)3896 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
3897 {
3898     auto task = [this, persistentId, isFocused]() {
3899         // notify session and client
3900         auto sceneSession = GetSceneSession(persistentId);
3901         if (sceneSession == nullptr) {
3902             WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
3903             return WSError::WS_ERROR_INVALID_WINDOW;
3904         }
3905         WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
3906             sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
3907         // focusId change
3908         if (isFocused) {
3909             SetFocusedSession(persistentId);
3910             UpdateBrightness(focusedSessionId_);
3911             FocusIDChange(persistentId, sceneSession);
3912         } else if (persistentId == GetFocusedSession()) {
3913             SetFocusedSession(INVALID_SESSION_ID);
3914         }
3915         // notify window manager
3916         sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
3917             sceneSession->GetWindowId(),
3918             static_cast<DisplayId>(0),
3919             sceneSession->GetCallingPid(),
3920             sceneSession->GetCallingUid(),
3921             sceneSession->GetWindowType(),
3922             sceneSession->GetAbilityToken()
3923         );
3924         SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
3925         WSError res = WSError::WS_OK;
3926         res = sceneSession->UpdateFocus(isFocused);
3927         if (res != WSError::WS_OK) {
3928             return res;
3929         }
3930         WLOGFI("UpdateFocus, id: %{public}d, isSystem: %{public}d", sceneSession->GetPersistentId(),
3931                sceneSession->GetSessionInfo().isSystem_);
3932         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
3933             if (isFocused) {
3934                 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
3935                 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
3936             } else {
3937                 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
3938                 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
3939             }
3940         }
3941         return WSError::WS_OK;
3942     };
3943 
3944     taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
3945     return WSError::WS_OK;
3946 }
3947 
UpdateWindowMode(int32_t persistentId,int32_t windowMode)3948 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
3949 {
3950     WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
3951     auto sceneSession = GetSceneSession(persistentId);
3952     if (sceneSession == nullptr) {
3953         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
3954         return WSError::WS_ERROR_INVALID_WINDOW;
3955     }
3956     WindowMode mode = static_cast<WindowMode>(windowMode);
3957     return sceneSession->UpdateWindowMode(mode);
3958 }
3959 
3960 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)3961 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3962     MMI::PointerEvent::PointerItem& pointerItem)
3963 {
3964     struct PointerEventData {
3965         double x;
3966         double y;
3967         uint64_t time;
3968     } pointerEventData = {
3969         .x = pointerItem.GetDisplayX(),
3970         .y = pointerItem.GetDisplayY(),
3971         .time = pointerEvent->GetActionTime()
3972     };
3973 
3974     const uint32_t MAX_HMAC_SIZE = 64;
3975     uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
3976     uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
3977     uint32_t enhanceDataLen = MAX_HMAC_SIZE;
3978     if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
3979         sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
3980         pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
3981     }
3982 }
3983 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
3984 
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)3985 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
3986 {
3987     if (!pointerEvent) {
3988         WLOGFE("pointerEvent is null");
3989         return WSError::WS_ERROR_NULLPTR;
3990     }
3991     MMI::PointerEvent::PointerItem pointerItem;
3992     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
3993         WLOGFE("Failed to get pointerItem");
3994         return WSError::WS_ERROR_INVALID_PARAM;
3995     }
3996 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
3997     FillSecCompEnhanceData(pointerEvent, pointerItem);
3998 #endif
3999     MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
4000     return WSError::WS_OK;
4001 }
4002 
SetScreenLocked(const bool isScreenLocked)4003 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
4004 {
4005     isScreenLocked_ = isScreenLocked;
4006 }
4007 
IsScreenLocked() const4008 bool SceneSessionManager::IsScreenLocked() const
4009 {
4010     return isScreenLocked_;
4011 }
4012 
RegisterWindowChanged(const WindowChangedFunc & func)4013 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
4014 {
4015     WindowChangedFunc_ = func;
4016 }
4017 
UpdatePrivateStateAndNotify(uint32_t persistentId)4018 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
4019 {
4020     int counts = GetSceneSessionPrivacyModeCount();
4021     bool hasPrivateWindow = (counts != 0);
4022     ScreenSessionManagerClient::GetInstance().SetScreenPrivacyState(hasPrivateWindow);
4023 }
4024 
GetSceneSessionPrivacyModeCount()4025 int SceneSessionManager::GetSceneSessionPrivacyModeCount()
4026 {
4027     auto countFunc = [](const std::pair<int32_t, sptr<SceneSession>>& sessionPair) -> bool {
4028         sptr<SceneSession> sceneSession = sessionPair.second;
4029         bool isForeground =  sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4030             sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
4031         if (isForeground && sceneSession->GetParentSession() != nullptr) {
4032             isForeground &= sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
4033             sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE;
4034         }
4035         bool isPrivate = sceneSession->GetSessionProperty() != nullptr &&
4036             sceneSession->GetSessionProperty()->GetPrivacyMode();
4037         bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
4038         return (isForeground || IsSystemWindowVisible) && isPrivate;
4039     };
4040     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4041     return std::count_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), countFunc);
4042 }
4043 
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)4044 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
4045 {
4046     NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
4047         this->OnSessionStateChange(persistentId, state);
4048     };
4049     if (sceneSession == nullptr) {
4050         WLOGFE("session is nullptr");
4051         return;
4052     }
4053     sceneSession->SetSessionStateChangeNotifyManagerListener(func);
4054     WLOGFD("RegisterSessionStateChangeFunc success");
4055 }
4056 
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)4057 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
4058 {
4059     wptr<SceneSessionManager> weakSessionManager = this;
4060     NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
4061         auto sceneSessionManager = weakSessionManager.promote();
4062         if (sceneSessionManager == nullptr) {
4063             return;
4064         }
4065         sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
4066     };
4067     if (sceneSession == nullptr) {
4068         WLOGFE("session is nullptr");
4069         return;
4070     }
4071     sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
4072 }
4073 
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)4074 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
4075 {
4076     NotifyRequestFocusStatusNotifyManagerFunc func =
4077     [this](int32_t persistentId, const bool isFocused, const bool byForeground) {
4078         this->RequestFocusStatus(persistentId, isFocused, byForeground);
4079     };
4080     if (sceneSession == nullptr) {
4081         WLOGFE("session is nullptr");
4082         return;
4083     }
4084     sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
4085     WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
4086 }
4087 
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)4088 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
4089 {
4090     GetStateFromManagerFunc func = [this](const ManagerState key) {
4091         switch (key)
4092         {
4093         case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
4094             return this->IsScreenLocked();
4095             break;
4096         default:
4097             return false;
4098             break;
4099         }
4100     };
4101     if (sceneSession == nullptr) {
4102         WLOGFE("session is nullptr");
4103         return;
4104     }
4105     sceneSession->SetGetStateFromManagerListener(func);
4106     WLOGFD("RegisterGetStateFromManagerFunc success");
4107 }
4108 
OnSessionStateChange(int32_t persistentId,const SessionState & state)4109 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
4110     int32_t persistentId, const SessionState& state)
4111 {
4112     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
4113     WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
4114     auto sceneSession = GetSceneSession(persistentId);
4115     if (sceneSession == nullptr) {
4116         WLOGFD("session is nullptr");
4117         return;
4118     }
4119     switch (state) {
4120         case SessionState::STATE_FOREGROUND:
4121             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
4122                 persistentId == focusedSessionId_) {
4123                 if (needBlockNotifyFocusStatusUntilForeground_) {
4124                     needBlockNotifyUnfocusStatus_ = false;
4125                     needBlockNotifyFocusStatusUntilForeground_ = false;
4126                     NotifyFocusStatus(sceneSession, true);
4127                 }
4128             } else {
4129                 RequestSessionFocus(persistentId, true);
4130             }
4131             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
4132             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
4133             HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
4134             UpdatePrivateStateAndNotify(persistentId);
4135             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4136                 ProcessSubSessionForeground(sceneSession);
4137             }
4138             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
4139                 ProcessPiPSessionForeground(sceneSession);
4140             }
4141             break;
4142         case SessionState::STATE_BACKGROUND:
4143             RequestSessionUnfocus(persistentId);
4144             UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
4145             NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
4146             HandleKeepScreenOn(sceneSession, false);
4147             UpdatePrivateStateAndNotify(persistentId);
4148             if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4149                 ProcessSubSessionBackground(sceneSession);
4150             }
4151             break;
4152         default:
4153             break;
4154     }
4155 }
4156 
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)4157 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
4158 {
4159     if (sceneSession == nullptr) {
4160         WLOGFD("session is nullptr");
4161         return;
4162     }
4163     for (const auto& subSession : sceneSession->GetSubSession()) {
4164         if (subSession == nullptr) {
4165             WLOGFD("sub session is nullptr");
4166             continue;
4167         }
4168         const auto& state = subSession->GetSessionState();
4169         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4170             WLOGFD("sub session is not active");
4171             continue;
4172         }
4173         RequestSessionFocus(subSession->GetPersistentId(), true);
4174         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
4175         HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
4176     }
4177     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
4178     for (const auto& dialog : dialogVec) {
4179         if (dialog == nullptr) {
4180             WLOGFD("[WMSDialog] dialog is nullptr");
4181             continue;
4182         }
4183         const auto& state = dialog->GetSessionState();
4184         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4185             WLOGFD("[WMSDialog] dialog is not active");
4186             continue;
4187         }
4188         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
4189         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
4190         if (dialog->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
4191             needBlockNotifyUnfocusStatus_ = false;
4192             needBlockNotifyFocusStatusUntilForeground_ = false;
4193             NotifyFocusStatus(dialogSession, true);
4194         }
4195         HandleKeepScreenOn(dialogSession, dialogSession->IsKeepScreenOn());
4196     }
4197 }
4198 
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)4199 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
4200 {
4201     // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
4202     sptr<SceneSession> mainSession = nullptr;
4203     if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4204         mainSession = sceneSession;
4205     } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
4206         mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
4207     }
4208     if (mainSession == nullptr) {
4209         WLOGFD("[WMSFocus]main window is nullptr");
4210         return WSError::WS_DO_NOTHING;
4211     }
4212     std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
4213     if (std::find_if(dialogVec.begin(), dialogVec.end(),
4214         [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
4215         != dialogVec.end()) {
4216             WLOGFD("[WMSDialog] dialog id: %{public}d has been focused!", focusedSessionId_);
4217             return WSError::WS_OK;
4218     }
4219     WSError ret = WSError::WS_DO_NOTHING;
4220     for (auto dialog : dialogVec) {
4221         if (dialog == nullptr) {
4222             continue;
4223         }
4224         // no need to consider order, since rule of zOrder
4225         if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
4226             ret = WSError::WS_OK;
4227         }
4228     }
4229     return ret;
4230 }
4231 
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)4232 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
4233 {
4234     if (sceneSession == nullptr) {
4235         WLOGFD("session is nullptr");
4236         return;
4237     }
4238     for (const auto& subSession : sceneSession->GetSubSession()) {
4239         if (subSession == nullptr) {
4240             WLOGFD("sub session is nullptr");
4241             continue;
4242         }
4243         const auto& state = subSession->GetSessionState();
4244         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4245             WLOGFD("sub session is not active");
4246             continue;
4247         }
4248         NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
4249         HandleKeepScreenOn(subSession, false);
4250         UpdatePrivateStateAndNotify(subSession->GetPersistentId());
4251     }
4252     std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
4253     for (const auto& dialog : dialogVec) {
4254         if (dialog == nullptr) {
4255             WLOGFD("[WMSDialog] dialog is nullptr");
4256             continue;
4257         }
4258         auto dialogSession = GetSceneSession(dialog->GetPersistentId());
4259         NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
4260         HandleKeepScreenOn(dialogSession, false);
4261         UpdatePrivateStateAndNotify(dialog->GetPersistentId());
4262     }
4263 }
4264 
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4265 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
4266     const sptr<WindowSessionProperty>& property)
4267 {
4268     if (sceneSession == nullptr) {
4269         WLOGFD("session is nullptr");
4270         return WSError::WS_ERROR_NULLPTR;
4271     }
4272     auto sessionProperty = sceneSession->GetSessionProperty();
4273     if (sessionProperty == nullptr) {
4274         return WSError::WS_ERROR_NULLPTR;
4275     }
4276     uint32_t flags = property->GetWindowFlags();
4277     uint32_t oldFlags = sessionProperty->GetWindowFlags();
4278     if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
4279         (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
4280         !property->GetSystemCalling()) {
4281             WLOGFE("Set window flags permission denied");
4282             return WSError::WS_ERROR_NOT_SYSTEM_APP;
4283     }
4284     sessionProperty->SetWindowFlags(flags);
4285     CheckAndNotifyWaterMarkChangedResult();
4286     if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
4287         sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
4288     }
4289     WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
4290     return WSError::WS_OK;
4291 }
4292 
CheckAndNotifyWaterMarkChangedResult()4293 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
4294 {
4295     bool currentWaterMarkShowState = false;
4296     {
4297         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4298         for (const auto& iter: sceneSessionMap_) {
4299             auto& session = iter.second;
4300             if (!session || !session->GetSessionProperty()) {
4301                 continue;
4302             }
4303             bool hasWaterMark = session->GetSessionProperty()->GetWindowFlags()
4304                 & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
4305             if (hasWaterMark && session->GetVisible()) {
4306                 currentWaterMarkShowState = true;
4307                 break;
4308             }
4309         }
4310     }
4311     if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
4312         lastWaterMarkShowState_ = currentWaterMarkShowState;
4313         NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
4314     }
4315     return;
4316 }
4317 
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)4318 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
4319 {
4320     WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
4321     SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
4322     return WSError::WS_OK;
4323 }
4324 
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const4325 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo &abilityInfo) const
4326 {
4327     if (!bundleMgr_) {
4328         WLOGFE("bundle manager is nullptr.");
4329         return;
4330     }
4331 
4332     AAFwk::Want want;
4333     want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
4334     auto uid = abilityInfo.uid;
4335     want.SetParam("uid", uid);
4336     bundleMgr_->ProcessPreload(want);
4337 }
4338 
NotifyCompleteFirstFrameDrawing(int32_t persistentId)4339 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
4340 {
4341     auto scnSession = GetSceneSession(persistentId);
4342     if (scnSession == nullptr) {
4343         WLOGFE("[WMSMain] scnSession is nullptr.");
4344         return;
4345     }
4346 
4347     const auto& sessionInfo = scnSession->GetSessionInfo();
4348     WLOGFI("[WMSMain] id: %{public}d, app info: [%{public}s %{public}s %{public}s]", scnSession->GetPersistentId(),
4349         sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
4350     auto abilityInfoPtr = sessionInfo.abilityInfo;
4351     if (abilityInfoPtr == nullptr) {
4352         WLOGFE("[WMSMain] abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
4353         return;
4354     }
4355     if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
4356         !(abilityInfoPtr->excludeFromMissions)) {
4357         WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
4358         listenerController_->NotifySessionCreated(persistentId);
4359     }
4360 
4361     if (taskScheduler_ == nullptr) {
4362         return;
4363     }
4364     auto task = [this, abilityInfoPtr]() {
4365         ProcessPreload(*abilityInfoPtr);
4366     };
4367     return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
4368 }
4369 
NotifySessionMovedToFront(int32_t persistentId)4370 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
4371 {
4372     WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
4373     auto scnSession = GetSceneSession(persistentId);
4374     if (scnSession == nullptr) {
4375         WLOGFE("session is invalid with %{public}d", persistentId);
4376         return;
4377     }
4378     WLOGFI("NotifySessionMovedToFront, id: %{public}d, isSystem: %{public}d", scnSession->GetPersistentId(),
4379            scnSession->GetSessionInfo().isSystem_);
4380     if (listenerController_ != nullptr &&
4381         !scnSession->GetSessionInfo().isSystem_ &&
4382         (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
4383         !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4384         listenerController_->NotifySessionMovedToFront(persistentId);
4385     }
4386 }
4387 
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)4388 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject> &token, const std::string &label)
4389 {
4390     WLOGFI("run SetSessionLabel");
4391 
4392     auto task = [this, &token, &label]() {
4393         auto sceneSession = FindSessionByToken(token);
4394         if (sceneSession == nullptr) {
4395             WLOGFI("fail to find session by token");
4396             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
4397         }
4398         sceneSession->SetSessionLabel(label);
4399         if (sessionListener_ != nullptr) {
4400             WLOGFI("try to run OnSessionLabelChange");
4401             sessionListener_->OnSessionLabelChange(sceneSession->GetPersistentId(), label);
4402         }
4403         WLOGFI("NotifySessionLabelUpdated, id: %{public}d, isSystem: %{public}d", sceneSession->GetPersistentId(),
4404             sceneSession->GetSessionInfo().isSystem_);
4405         if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
4406             WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
4407             listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
4408         }
4409         return WSError::WS_OK;
4410     };
4411     return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
4412 }
4413 
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)4414 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject> &token,
4415     const std::shared_ptr<Media::PixelMap> &icon)
4416 {
4417     WLOGFI("run SetSessionIcon");
4418     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4419         WLOGFE("The caller is not system-app, can not use system-api");
4420         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4421     }
4422 
4423     auto task = [this, &token, &icon]() {
4424         auto sceneSession = FindSessionByToken(token);
4425         if (sceneSession == nullptr) {
4426             WLOGFI("fail to find session by token");
4427             return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
4428         }
4429         sceneSession->SetSessionIcon(icon);
4430         if (sessionListener_ != nullptr) {
4431             WLOGFI("try to run OnSessionIconChange.");
4432             sessionListener_->OnSessionIconChange(sceneSession->GetPersistentId(), icon);
4433         }
4434         WLOGFI("NotifySessionIconChanged, id: %{public}d, isSystem: %{public}d", sceneSession->GetPersistentId(),
4435             sceneSession->GetSessionInfo().isSystem_);
4436         if (listenerController_ != nullptr &&
4437             !sceneSession->GetSessionInfo().isSystem_ &&
4438             (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
4439             !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4440             WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
4441             listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
4442         }
4443         return WSError::WS_OK;
4444     };
4445     return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
4446 }
4447 
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)4448 WSError SceneSessionManager::IsValidSessionIds(
4449     const std::vector<int32_t> &sessionIds, std::vector<bool> &results)
4450 {
4451     WLOGFI("run IsValidSessionIds");
4452     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4453     for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
4454         auto search = sceneSessionMap_.find(sessionIds.at(i));
4455         if (search == sceneSessionMap_.end() || search->second == nullptr) {
4456             results.push_back(false);
4457             continue;
4458         }
4459         results.push_back(true);
4460     }
4461     return WSError::WS_OK;
4462 }
4463 
RegisterSessionListener(const sptr<ISessionListener> & listener)4464 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
4465 {
4466     WLOGFI("run RegisterSessionListener");
4467     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4468         WLOGFE("The caller is not system-app, can not use system-api");
4469         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4470     }
4471     if (!SessionPermission::VerifySessionPermission()) {
4472         WLOGFE("The caller has not permission granted");
4473         return WSError::WS_ERROR_INVALID_PERMISSION;
4474     }
4475     auto task = [this, &listener]() {
4476         if (listenerController_ != nullptr) {
4477             return listenerController_->AddSessionListener(listener);
4478         } else {
4479             WLOGFE("The listenerController is nullptr");
4480             return WSError::WS_DO_NOTHING;
4481         }
4482     };
4483     return taskScheduler_->PostSyncTask(task, "AddSessionListener");
4484 }
4485 
UnRegisterSessionListener(const sptr<ISessionListener> & listener)4486 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
4487 {
4488     WLOGFI("run UnRegisterSessionListener");
4489     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4490         WLOGFE("The caller is not system-app, can not use system-api");
4491         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4492     }
4493     if (!SessionPermission::VerifySessionPermission()) {
4494         WLOGFE("The caller has not permission granted");
4495         return WSError::WS_ERROR_INVALID_PERMISSION;
4496     }
4497     auto task = [this, &listener]() {
4498         if (listenerController_ != nullptr) {
4499             listenerController_->DelSessionListener(listener);
4500             return WSError::WS_OK;
4501         } else {
4502             WLOGFE("The listenerController is nullptr");
4503             return WSError::WS_DO_NOTHING;
4504         }
4505     };
4506     return taskScheduler_->PostSyncTask(task, "DelSessionListener");
4507 }
4508 
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)4509 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
4510                                              std::vector<SessionInfoBean>& sessionInfos)
4511 {
4512     WLOGFI("run GetSessionInfos");
4513     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4514         WLOGFE("The caller is not system-app, can not use system-api");
4515         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4516     }
4517     if (!SessionPermission::VerifySessionPermission()) {
4518         WLOGFE("The caller has not permission granted");
4519         return WSError::WS_ERROR_INVALID_PERMISSION;
4520     }
4521     auto task = [this, &deviceId, numMax, &sessionInfos]() {
4522         if (CheckIsRemote(deviceId)) {
4523             int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
4524             if (ret != ERR_OK) {
4525                 return WSError::WS_ERROR_INVALID_PARAM;
4526             } else {
4527                 return WSError::WS_OK;
4528             }
4529         }
4530         std::map<int32_t, sptr<SceneSession>>::iterator iter;
4531         std::vector<sptr<SceneSession>> sceneSessionInfos;
4532         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4533         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
4534             auto sceneSession = iter->second;
4535             if (sceneSession == nullptr) {
4536                 WLOGFE("session is nullptr");
4537                 continue;
4538             }
4539             auto sessionInfo = sceneSession->GetSessionInfo();
4540             if (sessionInfo.isSystem_) {
4541                 WLOGFD("sessionId: %{public}d  isSystemScene", sceneSession->GetPersistentId());
4542                 continue;
4543             }
4544             auto want = sessionInfo.want;
4545             if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
4546                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
4547                     sceneSession->GetPersistentId());
4548                 continue;
4549             }
4550             if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
4551                 break;
4552             }
4553             WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
4554                 sessionInfo.bundleName_.c_str());
4555             sceneSessionInfos.emplace_back(sceneSession);
4556         }
4557         return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
4558     };
4559     return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
4560 }
4561 
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)4562 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
4563                                                std::vector<SessionInfoBean>& sessionInfos)
4564 {
4565     WLOGFI("GetRemoteSessionInfos From Dms begin");
4566     DistributedClient dmsClient;
4567     int result = dmsClient.GetMissionInfos(deviceId, numMax, sessionInfos);
4568     if (result != ERR_OK) {
4569         WLOGFE("GetRemoteMissionInfos failed, result = %{public}d", result);
4570         return result;
4571     }
4572     return ERR_OK;
4573 }
4574 
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)4575 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
4576                                             int32_t persistentId, SessionInfoBean& sessionInfo)
4577 {
4578     WLOGFI("run GetSessionInfo");
4579     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4580         WLOGFE("The caller is not system-app, can not use system-api");
4581         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4582     }
4583     if (!SessionPermission::VerifySessionPermission()) {
4584         WLOGFE("The caller has not permission granted");
4585         return WSError::WS_ERROR_INVALID_PERMISSION;
4586     }
4587     auto task = [this, &deviceId, persistentId, &sessionInfo]() {
4588         if (CheckIsRemote(deviceId)) {
4589             int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
4590             if (ret != ERR_OK) {
4591                 return WSError::WS_ERROR_INVALID_PARAM;
4592             } else {
4593                 return WSError::WS_OK;
4594             }
4595         }
4596         std::map<int32_t, sptr<SceneSession>>::iterator iter;
4597         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4598         iter = sceneSessionMap_.find(persistentId);
4599         if (iter != sceneSessionMap_.end()) {
4600             auto sceneSession = iter->second;
4601             if (sceneSession == nullptr) {
4602                 WLOGFE("session: %{public}d is nullptr", persistentId);
4603                 return WSError::WS_ERROR_INVALID_PARAM;
4604             }
4605             auto sceneSessionInfo = sceneSession->GetSessionInfo();
4606             if (sceneSessionInfo.isSystem_) {
4607                 WLOGFD("sessionId: %{public}d  isSystemScene", persistentId);
4608                 return WSError::WS_ERROR_INVALID_PARAM;
4609             }
4610             auto want = sceneSessionInfo.want;
4611             if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
4612                 want->GetElement().GetBundleName().empty()) {
4613                 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
4614                     persistentId);
4615                 return WSError::WS_ERROR_INTERNAL_ERROR;
4616             }
4617             WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
4618                 sceneSessionInfo.bundleName_.c_str());
4619             return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
4620         } else {
4621             WLOGFW("sessionId: %{public}d not found", persistentId);
4622             return WSError::WS_ERROR_INVALID_PARAM;
4623         }
4624     };
4625     return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
4626 }
4627 
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)4628 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
4629                                               int32_t persistentId, SessionInfoBean& sessionInfo)
4630 {
4631     WLOGFI("GetRemoteSessionInfoFromDms begin");
4632     std::vector<SessionInfoBean> sessionVector;
4633     int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
4634     if (result != ERR_OK) {
4635         return result;
4636     }
4637     for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
4638         if (iter->id == persistentId) {
4639             sessionInfo = *iter;
4640             return ERR_OK;
4641         }
4642     }
4643     WLOGFW("missionId not found");
4644     return ERR_INVALID_VALUE;
4645 }
4646 
CheckIsRemote(const std::string & deviceId)4647 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
4648 {
4649     if (deviceId.empty()) {
4650         WLOGFI("CheckIsRemote: deviceId is empty.");
4651         return false;
4652     }
4653     std::string localDeviceId;
4654     if (!GetLocalDeviceId(localDeviceId)) {
4655         WLOGFE("CheckIsRemote: get local deviceId failed");
4656         return false;
4657     }
4658     if (localDeviceId == deviceId) {
4659         WLOGFI("CheckIsRemote: deviceId is local.");
4660         return false;
4661     }
4662     WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
4663     return true;
4664 }
4665 
GetLocalDeviceId(std::string & localDeviceId)4666 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
4667 {
4668     auto localNode = std::make_unique<NodeBasicInfo>();
4669     int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
4670     if (errCode != ERR_OK) {
4671         WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
4672         return false;
4673     }
4674     if (localNode != nullptr) {
4675         localDeviceId = localNode->networkId;
4676         WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
4677         return true;
4678     }
4679     WLOGFE("localDeviceId null");
4680     return false;
4681 }
4682 
AnonymizeDeviceId(const std::string & deviceId)4683 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
4684 {
4685     if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
4686         return EMPTY_DEVICE_ID;
4687     }
4688     std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
4689     anonDeviceId.append("******");
4690     return anonDeviceId;
4691 }
4692 
DumpSessionAll(std::vector<std::string> & infos)4693 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string> &infos)
4694 {
4695     WLOGFI("Dump all session.");
4696     if (!SessionPermission::IsSystemCalling()) {
4697         WLOGFE("DumpSessionAll permission denied!");
4698         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4699     }
4700 
4701     auto task = [this, &infos]() {
4702         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
4703         infos.push_back(dumpInfo);
4704         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4705         for (const auto &item : sceneSessionMap_) {
4706             auto& session = item.second;
4707             if (session) {
4708                 session->DumpSessionInfo(infos);
4709             }
4710         }
4711         return WSError::WS_OK;
4712     };
4713 
4714     return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
4715 }
4716 
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)4717 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string> &infos)
4718 {
4719     WLOGFI("Dump session with id %{public}d", persistentId);
4720     if (!SessionPermission::IsSystemCalling()) {
4721         WLOGFE("DumpSessionWithId permission denied!");
4722         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4723     }
4724 
4725     auto task = [this, persistentId, &infos]() {
4726         std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
4727         infos.push_back(dumpInfo);
4728         auto session = GetSceneSession(persistentId);
4729         if (session) {
4730             session->DumpSessionInfo(infos);
4731         } else {
4732             infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
4733         }
4734         return WSError::WS_OK;
4735     };
4736 
4737     return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
4738 }
4739 
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<AppExecFwk::AbilityInfo> & abilityInfos)4740 WSError SceneSessionManager::GetAllAbilityInfos(const AAFwk::Want &want, int32_t userId,
4741     std::vector<AppExecFwk::AbilityInfo> &abilityInfos)
4742 {
4743     if (bundleMgr_ == nullptr) {
4744         WLOGFE("bundleMgr_ is nullptr");
4745         return WSError::WS_ERROR_NULLPTR;
4746     }
4747     auto elementName = want.GetElement();
4748     int32_t ret{0};
4749     auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
4750         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
4751         AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
4752         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
4753         static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
4754     std::vector<AppExecFwk::BundleInfo> bundleInfos;
4755     if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
4756         WLOGFD("want is empty queryAllAbilityInfos");
4757         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
4758         if (ret) {
4759             WLOGFE("Query all ability infos from BMS failed!");
4760             return WSError::WS_ERROR_INVALID_PARAM;
4761         }
4762     } else if (!elementName.GetBundleName().empty()) {
4763         AppExecFwk::BundleInfo bundleInfo;
4764         WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
4765         ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
4766         if (ret) {
4767             WLOGFE("Query ability info from BMS failed!");
4768             return WSError::WS_ERROR_INVALID_PARAM;
4769         }
4770         bundleInfos.push_back(bundleInfo);
4771     } else {
4772         WLOGFE("invalid want:%{public}s", want.ToString().c_str());
4773         return WSError::WS_ERROR_INVALID_PARAM;
4774     }
4775     return GetAbilityInfosFromBundleInfo(bundleInfos, abilityInfos);
4776 }
4777 
GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<AppExecFwk::AbilityInfo> & abilityInfos)4778 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo> &bundleInfos,
4779     std::vector<AppExecFwk::AbilityInfo> &abilityInfos)
4780 {
4781     if (bundleInfos.empty()) {
4782         WLOGFE("bundleInfos is empty");
4783         return WSError::WS_ERROR_INVALID_PARAM;
4784     }
4785     for (auto bundleInfo: bundleInfos) {
4786         auto hapModulesList = bundleInfo.hapModuleInfos;
4787         if (hapModulesList.empty()) {
4788             WLOGFD("hapModulesList is empty");
4789             continue;
4790         }
4791         for (auto hapModule: hapModulesList) {
4792             auto abilityInfoList = hapModule.abilityInfos;
4793             abilityInfos.insert(abilityInfos.end(), abilityInfoList.begin(), abilityInfoList.end());
4794         }
4795     }
4796     return WSError::WS_OK;
4797 }
4798 
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller)4799 WSError SceneSessionManager::TerminateSessionNew(const sptr<AAFwk::SessionInfo> info, bool needStartCaller)
4800 {
4801     if (info == nullptr) {
4802         WLOGFI("sessionInfo is nullptr.");
4803         return WSError::WS_ERROR_INVALID_PARAM;
4804     }
4805     WLOGFI("run TerminateSessionNew, bundleName=%{public}s, needStartCaller=%{public}d",
4806         info->want.GetElement().GetBundleName().c_str(), needStartCaller);
4807     auto task = [this, info, needStartCaller]() {
4808         sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
4809         if (sceneSession == nullptr) {
4810             WLOGFE("fail to find session by token.");
4811             return WSError::WS_ERROR_INVALID_PARAM;
4812         }
4813         const WSError& errCode = sceneSession->TerminateSessionNew(info, needStartCaller);
4814         return errCode;
4815     };
4816     return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
4817 }
4818 
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)4819 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
4820                                                 SessionSnapshot& snapshot, bool isLowResolution)
4821 {
4822     WLOGFI("run GetSessionSnapshot");
4823     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4824         WLOGFE("The caller is not system-app, can not use system-api");
4825         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4826     }
4827     if (!SessionPermission::VerifySessionPermission()) {
4828         WLOGFE("The caller has not permission granted");
4829         return WSError::WS_ERROR_INVALID_PERMISSION;
4830     }
4831     auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
4832         if (CheckIsRemote(deviceId)) {
4833             int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
4834             if (ret != ERR_OK) {
4835                 return WSError::WS_ERROR_INVALID_PARAM;
4836             } else {
4837                 return WSError::WS_OK;
4838             }
4839         }
4840         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4841         if (!sceneSession) {
4842             WLOGFE("fail to find session by persistentId: %{public}d", persistentId);
4843             return WSError::WS_ERROR_INVALID_PARAM;
4844         }
4845         auto sessionInfo = sceneSession->GetSessionInfo();
4846         if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
4847             WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
4848                    sceneSession->GetPersistentId());
4849         }
4850         snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
4851         snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
4852         snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
4853         auto oriSnapshot = sceneSession->Snapshot();
4854         if (oriSnapshot != nullptr) {
4855             if (isLowResolution) {
4856                 OHOS::Media::InitializationOptions options;
4857                 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
4858                 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
4859                 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
4860                 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
4861             } else {
4862                 snapshot.snapshot = oriSnapshot;
4863             }
4864         }
4865         return WSError::WS_OK;
4866     };
4867     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
4868 }
4869 
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)4870 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
4871                                                       AAFwk::MissionSnapshot& sessionSnapshot)
4872 {
4873     WLOGFI("GetRemoteSessionSnapshotInfo begin");
4874     std::unique_ptr<AAFwk::MissionSnapshot> sessionSnapshotPtr = std::make_unique<AAFwk::MissionSnapshot>();
4875     DistributedClient dmsClient;
4876     int result = dmsClient.GetRemoteMissionSnapshotInfo(deviceId, sessionId, sessionSnapshotPtr);
4877     if (result != ERR_OK) {
4878         WLOGFE("GetRemoteMissionSnapshotInfo failed, result = %{public}d", result);
4879         return result;
4880     }
4881     sessionSnapshot = *sessionSnapshotPtr;
4882     return ERR_OK;
4883 }
4884 
RegisterSessionListener(const sptr<ISessionChangeListener> sessionListener)4885 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionChangeListener> sessionListener)
4886 {
4887     WLOGFI("run RegisterSessionListener");
4888     if (sessionListener == nullptr) {
4889         return WSError::WS_ERROR_INVALID_SESSION_LISTENER;
4890     }
4891     if (!SessionPermission::VerifySessionPermission()) {
4892         WLOGFE("The caller has not permission granted");
4893         return WSError::WS_ERROR_INVALID_PERMISSION;
4894     }
4895     auto task = [this, sessionListener]() {
4896         sessionListener_ = sessionListener;
4897         return WSError::WS_OK;
4898     };
4899     return taskScheduler_->PostSyncTask(task, "RegisterSessionListener");
4900 }
4901 
UnregisterSessionListener()4902 void SceneSessionManager::UnregisterSessionListener()
4903 {
4904     if (!SessionPermission::VerifySessionPermission()) {
4905         WLOGFE("The caller has not permission granted");
4906         return;
4907     }
4908     auto task = [this]() {
4909         sessionListener_ = nullptr;
4910     };
4911     taskScheduler_->PostAsyncTask(task, "UnregisterSessionListener");
4912 }
4913 
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)4914 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
4915 {
4916     wptr<SceneSession> weakSceneSession(sceneSession);
4917     auto task = [this, weakSceneSession]() {
4918         auto scnSession = weakSceneSession.promote();
4919         if (scnSession == nullptr) {
4920             WLOGFE("session is nullptr");
4921             return WSError::WS_ERROR_NULLPTR;
4922         }
4923         auto persistentId = scnSession->GetPersistentId();
4924         WLOGFI("[WMSMain]RequestSceneSessionByCall persistentId: %{public}d", persistentId);
4925         if (!GetSceneSession(persistentId)) {
4926             WLOGFE("session is invalid with %{public}d", persistentId);
4927             return WSError::WS_ERROR_INVALID_SESSION;
4928         }
4929         auto sessionInfo = scnSession->GetSessionInfo();
4930         auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
4931         if (!abilitySessionInfo) {
4932             return WSError::WS_ERROR_NULLPTR;
4933         }
4934         if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
4935             scnSession->SetActive(false);
4936         } else if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::FOREGROUND)) {
4937             scnSession->SetActive(true);
4938         } else {
4939             WLOGFE("wrong callState_");
4940         }
4941         WLOGFI("[WMSMain]RequestSceneSessionByCall callState:%{public}d, persistentId: %{public}d",
4942             sessionInfo.callState_, persistentId);
4943         AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo);
4944         scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
4945         return WSError::WS_OK;
4946     };
4947     std::string taskName = "RequestSceneSessionByCall:PID:" +
4948         (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
4949     taskScheduler_->PostAsyncTask(task, taskName);
4950     return WSError::WS_OK;
4951 }
4952 
StartAbilityBySpecified(const SessionInfo & sessionInfo)4953 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
4954 {
4955     auto task = [this, sessionInfo]() {
4956         WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
4957             sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
4958         AAFwk::Want want;
4959         want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
4960         AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
4961     };
4962 
4963     taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
4964 }
4965 
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)4966 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
4967 {
4968     if (!targetToken) {
4969         WLOGFE("Token is null, cannot find main window");
4970         return nullptr;
4971     }
4972 
4973     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4974     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
4975         [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
4976             if (pair.second->IsTerminated()) {
4977                 return false;
4978             }
4979             if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4980                 return pair.second->GetAbilityToken() == targetToken;
4981             }
4982             return false;
4983         });
4984     if (iter == sceneSessionMap_.end()) {
4985         WLOGFE("Cannot find session");
4986         return nullptr;
4987     }
4988     return iter->second;
4989 }
4990 
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)4991 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
4992 {
4993     if (!SessionPermission::IsSystemCalling()) {
4994         WLOGFE("[WMSDialog] BindDialogSessionTarget permission denied!");
4995         return WSError::WS_ERROR_NOT_SYSTEM_APP;
4996     }
4997     if (targetToken == nullptr) {
4998         WLOGFE("[WMSDialog] Target token is null");
4999         return WSError::WS_ERROR_NULLPTR;
5000     }
5001 
5002     auto task = [this, persistentId, targetToken]() {
5003         auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
5004         if (scnSession == nullptr) {
5005             WLOGFE("[WMSDialog] Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
5006             return WSError::WS_ERROR_NULLPTR;
5007         }
5008         if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
5009             WLOGFE("[WMSDialog] Session is not dialog window, window type:%{public}u", scnSession->GetWindowType());
5010             return WSError::WS_OK;
5011         }
5012         scnSession->dialogTargetToken_ = targetToken;
5013         sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
5014         if (parentSession == nullptr) {
5015             scnSession->NotifyDestroy();
5016             return WSError::WS_ERROR_INVALID_PARAM;
5017         }
5018         scnSession->SetParentSession(parentSession);
5019         scnSession->SetParentPersistentId(parentSession->GetPersistentId());
5020         UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
5021         WLOGFI("[WMSDialog] Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
5022             persistentId, parentSession->GetPersistentId());
5023         return WSError::WS_OK;
5024     };
5025     return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
5026 }
5027 
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds)5028 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
5029     std::vector<uint64_t>& surfaceNodeIds)
5030 {
5031     SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds);
5032 }
5033 
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds)5034 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
5035     std::vector<uint64_t>& surfaceNodeIds)
5036 {
5037     auto isSaCall = SessionPermission::IsSACalling();
5038     if (!isSaCall) {
5039         WLOGFE("The interface only support for sa call");
5040         return WMError::WM_ERROR_INVALID_PERMISSION;
5041     }
5042     auto task = [this, &missionIds, &surfaceNodeIds]() {
5043         std::map<int32_t, sptr<SceneSession>>::iterator iter;
5044         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5045         for (auto missionId : missionIds) {
5046             iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
5047             if (iter == sceneSessionMap_.end()) {
5048                 continue;
5049             }
5050             auto sceneSession = iter->second;
5051             if (sceneSession == nullptr) {
5052                 continue;
5053             }
5054             if (sceneSession->GetSurfaceNode() == nullptr) {
5055                 continue;
5056             }
5057             surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
5058             if (sceneSession->GetLeashWinSurfaceNode()) {
5059                 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
5060             }
5061         }
5062         return WMError::WM_OK;
5063     };
5064     return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
5065 }
5066 
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)5067 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
5068     const sptr<IWindowManagerAgent>& windowManagerAgent)
5069 {
5070     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
5071         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
5072         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
5073         if (!SessionPermission::IsSystemCalling()) {
5074             WLOGFE("RegisterWindowManagerAgent permission denied!");
5075             return WMError::WM_ERROR_NOT_SYSTEM_APP;
5076         }
5077     }
5078     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
5079         WLOGFE("windowManagerAgent is null");
5080         return WMError::WM_ERROR_NULLPTR;
5081     }
5082     auto task = [this, &windowManagerAgent, type]() {
5083         return SessionManagerAgentController::GetInstance().RegisterWindowManagerAgent(windowManagerAgent, type);
5084     };
5085     return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
5086 }
5087 
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)5088 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
5089     const sptr<IWindowManagerAgent>& windowManagerAgent)
5090 {
5091     if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
5092         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
5093         type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
5094         if (!SessionPermission::IsSystemCalling()) {
5095             WLOGFE("UnregisterWindowManagerAgent permission denied!");
5096             return WMError::WM_ERROR_NOT_SYSTEM_APP;
5097         }
5098     }
5099     if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
5100         WLOGFE("windowManagerAgent is null");
5101         return WMError::WM_ERROR_NULLPTR;
5102     }
5103     auto task = [this, &windowManagerAgent, type]() {
5104         return SessionManagerAgentController::GetInstance().UnregisterWindowManagerAgent(windowManagerAgent, type);
5105     };
5106     return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
5107 }
5108 
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)5109 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
5110 {
5111     SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
5112 }
5113 
StartWindowInfoReportLoop()5114 void SceneSessionManager::StartWindowInfoReportLoop()
5115 {
5116     WLOGFD("Report loop");
5117     if (eventHandler_ == nullptr) {
5118         WLOGFE("Report event null");
5119         return ;
5120     }
5121     if (isReportTaskStart_) {
5122         WLOGFE("Report is ReportTask Start");
5123         return;
5124     }
5125     auto task = [this]() {
5126         WindowInfoReporter::GetInstance().ReportRecordedInfos();
5127         isReportTaskStart_ = false;
5128         StartWindowInfoReportLoop();
5129     };
5130     int64_t delayTime = 1000 * 60 * 60; // an hour.
5131     bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
5132     if (!ret) {
5133         WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
5134         return;
5135     }
5136     isReportTaskStart_ = true;
5137 }
5138 
GetStatusBarHeight()5139 int32_t SceneSessionManager::GetStatusBarHeight()
5140 {
5141     int32_t statusBarHeight = 0;
5142     int32_t height = 0;
5143     std::vector<sptr<SceneSession>> statusBarVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR);
5144     for (auto& statusBar : statusBarVector) {
5145         if (statusBar == nullptr || !IsSessionVisible(statusBar)) {
5146             continue;
5147         }
5148         height = statusBar->GetSessionRect().height_;
5149         statusBarHeight = (statusBarHeight > height) ? statusBarHeight : height;
5150     }
5151 
5152     return statusBarHeight;
5153 }
5154 
ResizeSoftInputCallingSessionIfNeed(const sptr<SceneSession> & sceneSession,bool isInputUpdated)5155 void SceneSessionManager::ResizeSoftInputCallingSessionIfNeed(
5156     const sptr<SceneSession>& sceneSession, bool isInputUpdated)
5157 {
5158     if (callingSession_ == nullptr) {
5159         WLOGFI("[WMSInput] calling session is nullptr");
5160         return;
5161     }
5162     SessionGravity gravity;
5163     uint32_t percent = 0;
5164     sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
5165     if (gravity != SessionGravity::SESSION_GRAVITY_BOTTOM && gravity != SessionGravity::SESSION_GRAVITY_DEFAULT) {
5166         WLOGFI("[WMSInput] Gravity is not bottom, no need to raise calling window, gravity: %{public}d", gravity);
5167         return;
5168     }
5169 
5170     bool isCallingSessionFloating;
5171     if (callingSession_->GetSessionProperty() &&
5172         callingSession_->GetSessionProperty()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
5173         isCallingSessionFloating = true;
5174     } else {
5175         isCallingSessionFloating = false;
5176     }
5177 
5178     const WSRect& softInputSessionRect = sceneSession->GetSessionRect();
5179     WSRect callingSessionRect;
5180     if (isInputUpdated && isCallingSessionFloating) {
5181         callingSessionRect = callingWindowRestoringRect_;
5182     } else {
5183         callingSessionRect = callingSession_->GetSessionRect();
5184     }
5185     WLOGFI("[WMSInput] softInputSessionRect: %{public}s, callingSessionRect: %{public}s",
5186         softInputSessionRect.ToString().c_str(), callingSessionRect.ToString().c_str());
5187     if (SessionHelper::IsEmptyRect(SessionHelper::GetOverlap(softInputSessionRect, callingSessionRect, 0, 0))) {
5188         WLOGFD("[WMSInput] There is no overlap area");
5189         return;
5190     }
5191 
5192     WSRect newRect = callingSessionRect;
5193     int32_t statusHeight = GetStatusBarHeight();
5194     if (isCallingSessionFloating && callingSessionRect.posY_ > statusHeight) {
5195         // calculate new rect of calling window
5196         newRect.posY_ = softInputSessionRect.posY_ - static_cast<int32_t>(newRect.height_);
5197         newRect.posY_ = std::max(newRect.posY_, statusHeight);
5198     }
5199 
5200     if (!isInputUpdated) {
5201         callingWindowRestoringRect_ = callingSessionRect;
5202     }
5203     NotifyOccupiedAreaChangeInfo(sceneSession, newRect, softInputSessionRect);
5204     if (isCallingSessionFloating && callingSessionRect.posY_ > statusHeight) {
5205         needUpdateSessionRect_ = true;
5206         callingSession_->UpdateSessionRect(newRect, SizeChangeReason::UNDEFINED);
5207         callingWindowNewRect_ = callingSession_->GetSessionRect();
5208     }
5209 }
5210 
NotifyOccupiedAreaChangeInfo(const sptr<SceneSession> sceneSession,const WSRect & rect,const WSRect & occupiedArea)5211 void SceneSessionManager::NotifyOccupiedAreaChangeInfo(const sptr<SceneSession> sceneSession,
5212     const WSRect& rect, const WSRect& occupiedArea)
5213 {
5214     // if keyboard will occupy calling, notify calling window the occupied area and safe height
5215     const WSRect& safeRect = SessionHelper::GetOverlap(occupiedArea, rect, 0, 0);
5216     const WSRect& lastSafeRect = callingSession_->GetLastSafeRect();
5217     if (lastSafeRect == safeRect) {
5218         WLOGFI("[WMSInput] NotifyOccupiedAreaChangeInfo lastSafeRect is same to safeRect");
5219         return;
5220     }
5221     callingSession_->SetLastSafeRect(safeRect);
5222     sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
5223         SessionHelper::TransferToRect(safeRect), safeRect.height_,
5224         sceneSession->textFieldPositionY_, sceneSession->textFieldHeight_);
5225     WLOGFD("[WMSInput] OccupiedAreaChangeInfo rect: %{public}u %{public}u %{public}u %{public}u",
5226         occupiedArea.posX_, occupiedArea.posY_, occupiedArea.width_, occupiedArea.height_);
5227     callingSession_->NotifyOccupiedAreaChangeInfo(info);
5228 }
5229 
RestoreCallingSessionSizeIfNeed()5230 void SceneSessionManager::RestoreCallingSessionSizeIfNeed()
5231 {
5232     WLOGFD("[WMSInput] RestoreCallingSessionSizeIfNeed");
5233     if (callingSession_ == nullptr) {
5234         WLOGFI("[WMSInput] Calling session is nullptr");
5235         return;
5236     }
5237 
5238     if (!SessionHelper::IsEmptyRect(callingWindowRestoringRect_)) {
5239         WSRect overlapRect = { 0, 0, 0, 0 };
5240         NotifyOccupiedAreaChangeInfo(callingSession_, callingWindowRestoringRect_, overlapRect);
5241         if (needUpdateSessionRect_ && callingSession_->GetSessionProperty() &&
5242             callingSession_->GetSessionProperty()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
5243             callingSession_->GetSessionRect() == callingWindowNewRect_) {
5244             callingSession_->UpdateSessionRect(callingWindowRestoringRect_, SizeChangeReason::UNDEFINED);
5245         }
5246     }
5247     needUpdateSessionRect_ = false;
5248     callingWindowRestoringRect_ = { 0, 0, 0, 0 };
5249 }
5250 
SetSessionGravity(int32_t persistentId,SessionGravity gravity,uint32_t percent)5251 WSError SceneSessionManager::SetSessionGravity(int32_t persistentId, SessionGravity gravity, uint32_t percent)
5252 {
5253     auto task = [this, persistentId, gravity, percent]() -> WSError {
5254         auto sceneSession = GetSceneSession(persistentId);
5255         if (!sceneSession) {
5256             WLOGFE("scene session is nullptr");
5257             return WSError::WS_ERROR_NULLPTR;
5258         }
5259         WLOGFI("[WMSInput] SetSessionGravity persistentId: %{public}d, windowType: %{public}d, gravity: %{public}d",
5260             persistentId, sceneSession->GetWindowType(), gravity);
5261         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
5262             WLOGFE("[WMSInput] scene session is not input method");
5263             return WSError::WS_ERROR_INVALID_TYPE;
5264         }
5265         sceneSession->GetSessionProperty()->SetSessionGravity(gravity, percent);
5266         RelayoutKeyBoard(sceneSession);
5267         if (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
5268             sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) {
5269             WLOGFI("[WMSInput] InputMethod is not foreground, not need to adjust or restore callingWindow");
5270             return WSError::WS_OK;
5271         }
5272         if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
5273             WLOGFD("[WMSInput] input method is float mode");
5274             sceneSession->SetWindowAnimationFlag(false);
5275             RestoreCallingSessionSizeIfNeed();
5276         } else {
5277             WLOGFD("[WMSInput] input method is bottom mode");
5278             sceneSession->SetWindowAnimationFlag(true);
5279             ResizeSoftInputCallingSessionIfNeed(sceneSession);
5280         }
5281         return WSError::WS_OK;
5282     };
5283     taskScheduler_->PostAsyncTask(task, "SetSessionGravity" + std::to_string(persistentId));
5284     return WSError::WS_OK;
5285 }
5286 
RelayoutKeyBoard(sptr<SceneSession> sceneSession)5287 void SceneSessionManager::RelayoutKeyBoard(sptr<SceneSession> sceneSession)
5288 {
5289     if (sceneSession == nullptr) {
5290         WLOGFE("[WMSInput] sceneSession is nullptr");
5291         return;
5292     }
5293     SessionGravity gravity;
5294     uint32_t percent = 0;
5295     sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
5296     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
5297         gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
5298         return;
5299     }
5300 
5301     auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
5302     if (defaultDisplayInfo == nullptr) {
5303         WLOGFE("[WMSInput] screenSession is null");
5304         return;
5305     }
5306 
5307     auto requestRect = sceneSession->GetSessionProperty()->GetRequestRect();
5308     if (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) {
5309         requestRect.width_ = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
5310         requestRect.posX_ = 0;
5311         if (percent != 0) {
5312             requestRect.height_ =
5313                 static_cast<uint32_t>(defaultDisplayInfo->GetHeight()) * percent / 100u; // 100: for calc percent.
5314         }
5315     }
5316     requestRect.posY_ = defaultDisplayInfo->GetHeight() -
5317         static_cast<int32_t>(requestRect.height_);
5318     sceneSession->GetSessionProperty()->SetRequestRect(requestRect);
5319     WLOGFD("[WMSInput] Id: %{public}d, rect: %{public}s", sceneSession->GetPersistentId(),
5320         SessionHelper::TransferToWSRect(requestRect).ToString().c_str());
5321     sceneSession->UpdateSessionRect(SessionHelper::TransferToWSRect(requestRect), SizeChangeReason::UNDEFINED);
5322 }
5323 
InitPersistentStorage()5324 void SceneSessionManager::InitPersistentStorage()
5325 {
5326     if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
5327         int32_t storageMode = -1;
5328         ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
5329         if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
5330             storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
5331             WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
5332             SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
5333         }
5334     }
5335 }
5336 
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)5337 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
5338 {
5339     WLOGFI("GetAccessibilityWindowInfo Called.");
5340     if (!SessionPermission::IsSystemServiceCalling()) {
5341         WLOGFE("The interface only support for system service.");
5342         return WMError::WM_ERROR_NOT_SYSTEM_APP;
5343     }
5344     auto task = [this, &infos]() {
5345         std::map<int32_t, sptr<SceneSession>>::iterator iter;
5346         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5347         for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
5348             sptr<SceneSession> sceneSession = iter->second;
5349             if (sceneSession == nullptr) {
5350                 WLOGFW("null scene session");
5351                 continue;
5352             }
5353             WLOGFD("name = %{public}s, isSystem = %{public}d, persistendId = %{public}d, winType = %{public}d, "
5354                 "state = %{public}d, visible = %{public}d", sceneSession->GetWindowName().c_str(),
5355                 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
5356                 sceneSession->GetSessionState(), sceneSession->IsVisibleForAccessibility());
5357             if (sceneSession->IsVisibleForAccessibility()) {
5358                 FillWindowInfo(infos, iter->second);
5359             }
5360         }
5361         return WMError::WM_OK;
5362     };
5363     return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
5364 }
5365 
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)5366 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
5367 {
5368     WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
5369     sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
5370     if (sceneSession == nullptr) {
5371         WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
5372         return;
5373     }
5374     wptr<SceneSession> weakSceneSession(sceneSession);
5375     auto task = [this, weakSceneSession, type]() {
5376         std::vector<sptr<AccessibilityWindowInfo>> infos;
5377         auto scnSession = weakSceneSession.promote();
5378         if (FillWindowInfo(infos, scnSession)) {
5379             SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(infos, type);
5380         }
5381         if (WindowChangedFunc_ != nullptr && scnSession != nullptr &&
5382             scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5383             WindowChangedFunc_(scnSession->GetPersistentId(), type);
5384         }
5385     };
5386     taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
5387 
5388     auto notifySceneInputTask = [weakSceneSession, type]() {
5389         auto scnSession = weakSceneSession.promote();
5390         if (scnSession == nullptr) {
5391             return;
5392         }
5393         SceneInputManager::GetInstance().NotifyWindowInfoChange(scnSession, type);
5394     };
5395     taskScheduler_->PostAsyncTask(notifySceneInputTask);
5396 }
5397 
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)5398 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
5399     const sptr<SceneSession>& sceneSession)
5400 {
5401     if (sceneSession == nullptr) {
5402         WLOGFW("null scene session.");
5403         return false;
5404     }
5405     if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos
5406         || sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos) {
5407         WLOGFD("filter gesture window.");
5408         return false;
5409     }
5410     sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
5411     if (info == nullptr) {
5412         WLOGFE("null info.");
5413         return false;
5414     }
5415     if (sceneSession->GetSessionInfo().isSystem_) {
5416         info->wid_ = 1;
5417         info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
5418     } else {
5419         info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
5420     }
5421     info->uiNodeId_ = sceneSession->GetUINodeId();
5422     WSRect wsrect = sceneSession->GetSessionRect();
5423     info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
5424     info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
5425     info->type_ = sceneSession->GetWindowType();
5426     info->mode_ = sceneSession->GetWindowMode();
5427     info->layer_ = sceneSession->GetZOrder();
5428     info->scaleVal_ = sceneSession->GetFloatingScale();
5429     info->scaleX_ = sceneSession->GetScaleX();
5430     info->scaleY_ = sceneSession->GetScaleY();
5431     auto property = sceneSession->GetSessionProperty();
5432     if (property != nullptr) {
5433         info->displayId_ = property->GetDisplayId();
5434         info->isDecorEnable_ = property->IsDecorEnable();
5435     }
5436     infos.emplace_back(info);
5437     WLOGFD("wid = %{public}d, inWid = %{public}d, uiNId = %{public}d", info->wid_, info->innerWid_, info->uiNodeId_);
5438     return true;
5439 }
5440 
GetSessionSnapshotFilePath(int32_t persistentId)5441 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
5442 {
5443     WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
5444     auto sceneSession = GetSceneSession(persistentId);
5445     if (sceneSession == nullptr) {
5446         WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
5447         return "";
5448     }
5449     wptr<SceneSession> weakSceneSession(sceneSession);
5450     auto task = [this, weakSceneSession]() {
5451         auto scnSession = weakSceneSession.promote();
5452         if (scnSession == nullptr) {
5453             WLOGFE("session is nullptr");
5454             return std::string("");
5455         }
5456         std::string filePath = scnSession->GetSessionSnapshotFilePath();
5457         return filePath;
5458     };
5459     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
5460 }
5461 
SelectSesssionFromMap(const uint64_t & surfaceId)5462 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
5463 {
5464     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5465     for (const auto &item : sceneSessionMap_) {
5466         auto sceneSession = item.second;
5467         if (sceneSession == nullptr) {
5468             continue;
5469         }
5470         if (sceneSession->GetSurfaceNode() == nullptr) {
5471             continue;
5472         }
5473         if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
5474             return sceneSession;
5475         }
5476     }
5477     return nullptr;
5478 }
5479 
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)5480 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
5481 {
5482     WLOGFD("WindowLayerInfoChangeCallback: entry");
5483     std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
5484 
5485     auto task = [this, weak]() {
5486         auto weakOcclusionData = weak.lock();
5487         if (weakOcclusionData == nullptr) {
5488             WLOGFE("weak occlusionData is nullptr");
5489             return;
5490         }
5491         std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
5492         std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
5493         GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
5494         std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
5495         if (currVisibleData.size() != 0) {
5496             visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
5497         }
5498         if (visibilityChangeInfos.size() != 0) {
5499             DealwithVisibilityChange(visibilityChangeInfos);
5500         }
5501 
5502         std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
5503         if (currDrawingContentData.size() != 0) {
5504             drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
5505         }
5506         if (drawingContentChangeInfos.size() != 0) {
5507             DealwithDrawingContentChange(drawingContentChangeInfos);
5508         }
5509     };
5510     taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
5511 }
5512 
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)5513 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
5514     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
5515     std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
5516 {
5517     VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
5518     for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
5519         WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
5520         switch (windowLayerState) {
5521             case WINDOW_ALL_VISIBLE:
5522             case WINDOW_SEMI_VISIBLE:
5523             case WINDOW_IN_VISIBLE:
5524                 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
5525                 break;
5526             case WINDOW_LAYER_DRAWING:
5527                 currDrawingContentData.emplace_back(iter->first, true);
5528                 break;
5529             case WINDOW_LAYER_NO_DRAWING:
5530                 currDrawingContentData.emplace_back(iter->first, false);
5531                 break;
5532             default:
5533                 break;
5534         }
5535     }
5536 }
5537 
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)5538 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
5539     std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
5540 {
5541     std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
5542     std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
5543     uint32_t i, j;
5544     i = j = 0;
5545     for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
5546         if (lastVisibleData_[i].first < currVisibleData[j].first) {
5547             visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
5548             i++;
5549         } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
5550             visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
5551             j++;
5552         } else {
5553             if (lastVisibleData_[i].second != currVisibleData[j].second) {
5554                 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
5555             }
5556             i++;
5557             j++;
5558         }
5559     }
5560     for (; i < lastVisibleData_.size(); ++i) {
5561         visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
5562     }
5563     for (; j < currVisibleData.size(); ++j) {
5564         visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
5565     }
5566     lastVisibleData_ = currVisibleData;
5567     return visibilityChangeInfo;
5568 }
5569 
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo)5570 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
5571     visibilityChangeInfo)
5572 {
5573     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
5574 #ifdef MEMMGR_WINDOW_ENABLE
5575     std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
5576 #endif
5577 
5578     std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
5579     for (const auto& elem : visibilityChangeInfo) {
5580         uint64_t surfaceId = elem.first;
5581         WindowVisibilityState visibleState = elem.second;
5582         bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
5583         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
5584         if (session == nullptr) {
5585             continue;
5586         }
5587         if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
5588             session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
5589             if (session->GetParentSession() != nullptr &&
5590                 !session->GetParentSession()->IsSessionForeground()) {
5591                     continue;
5592                 }
5593         }
5594         session->SetVisible(isVisible);
5595         session->SetVisibilityState(visibleState);
5596         int32_t windowId = session->GetWindowId();
5597         if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
5598             session->NotifyWindowVisibility();
5599         }
5600         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(windowId, session->GetCallingPid(),
5601             session->GetCallingUid(), visibleState, session->GetWindowType()));
5602 #ifdef MEMMGR_WINDOW_ENABLE
5603     memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
5604             session->GetCallingUid(), isVisible));
5605 #endif
5606         visibilityInfo += "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " +
5607             std::to_string(visibleState) + "], ";
5608         CheckAndNotifyWaterMarkChangedResult();
5609     }
5610     if (windowVisibilityInfos.size() != 0) {
5611         WLOGI("Notify windowvisibilityinfo changed start, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
5612             visibilityInfo.c_str());
5613         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
5614     }
5615 #ifdef MEMMGR_WINDOW_ENABLE
5616     if (memMgrWindowInfos.size() != 0) {
5617         WLOGD("Notify memMgrWindowInfos changed start");
5618         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
5619     }
5620 #endif
5621 }
5622 
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)5623 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
5624     drawingContentChangeInfo)
5625 {
5626     std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
5627     for (const auto& elem : drawingContentChangeInfo) {
5628         uint64_t surfaceId = elem.first;
5629         bool drawingState = elem.second;
5630         sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
5631         if (session == nullptr) {
5632             continue;
5633         }
5634         windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
5635             session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
5636         if (openDebugTrace) {
5637             HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
5638                 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
5639         }
5640         WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
5641             "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
5642     }
5643     if (windowDrawingContenInfos.size() != 0) {
5644         WLOGFD("Notify WindowDrawingContenInfo changed start");
5645         SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
5646     }
5647 }
5648 
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)5649 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
5650     std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
5651 {
5652     std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
5653     for (const auto& data : currDrawingContentData) {
5654         uint64_t windowId = data.first;
5655         bool currentDrawingContentState = data.second;
5656         int32_t pid = 0;
5657         bool isChange = false;
5658         if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
5659             continue;
5660         } else {
5661             isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
5662         }
5663 
5664         if (isChange) {
5665             processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
5666         }
5667     }
5668     return processDrawingContentChangeInfo;
5669 }
5670 
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)5671 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
5672 {
5673     bool preWindowDrawingState = true;
5674     sptr<SceneSession> session = SelectSesssionFromMap(windowId);
5675     if (session == nullptr) {
5676         return false;
5677     }
5678     pid = session->GetCallingPid();
5679     preWindowDrawingState = session->GetDrawingContentState();
5680     session->SetDrawingContentState(currentDrawingContentState);
5681     return preWindowDrawingState;
5682 }
5683 
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)5684 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
5685 {
5686     bool isChange = true;
5687     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5688     for (const auto& item : sceneSessionMap_) {
5689         auto sceneSession = item.second;
5690         if (sceneSession == nullptr) {
5691             continue;
5692         }
5693         if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
5694             windowId != sceneSession->GetSurfaceNode()->GetId()) {
5695                 if (sceneSession->GetDrawingContentState()) {
5696                     return false;
5697                 }
5698             }
5699         }
5700     return isChange;
5701 }
5702 
5703 
InitWithRenderServiceAdded()5704 void SceneSessionManager::InitWithRenderServiceAdded()
5705 {
5706     auto windowVisibilityChangeCb = std::bind(&SceneSessionManager::WindowLayerInfoChangeCallback, this,
5707         std::placeholders::_1);
5708     WLOGI("RegisterWindowVisibilityChangeCallback");
5709     if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
5710         WLOGFE("RegisterWindowVisibilityChangeCallback failed");
5711     }
5712 }
5713 
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)5714 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
5715 {
5716     if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
5717         WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
5718         return WMError::WM_ERROR_INVALID_PARAM;
5719     }
5720 
5721     auto task = [this, sceneType]() {
5722         WLOGFD("Set system animated scene %{public}d.", sceneType);
5723         bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
5724         if (!ret) {
5725             WLOGFE("Set system animated scene failed.");
5726         }
5727     };
5728     taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
5729     return WMError::WM_OK;
5730 }
5731 
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)5732 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
5733 {
5734     if (!SessionPermission::IsSystemCalling()) {
5735         WLOGFE("NotifyWindowExtensionVisibilityChange permission denied!");
5736         return WSError::WS_ERROR_NOT_SYSTEM_APP;
5737     }
5738     WLOGFI("Notify WindowExtension visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
5739         visible ? "VISIBLE" : "INVISIBLE", pid, uid);
5740     std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
5741     windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
5742         visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
5743         WindowType::WINDOW_TYPE_APP_COMPONENT));
5744     SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
5745     return WSError::WS_OK;
5746 }
5747 
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)5748 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
5749 {
5750     if (sceneSession == nullptr) {
5751         WLOGFE("sceneSession is nullptr!");
5752         return;
5753     }
5754     if (sceneSession->GetVisible()) {
5755         std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
5756 #ifdef MEMMGR_WINDOW_ENABLE
5757         std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
5758 #endif
5759         sceneSession->SetVisible(false);
5760         sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
5761         windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
5762             sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
5763             WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
5764 #ifdef MEMMGR_WINDOW_ENABLE
5765         memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
5766         sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
5767 #endif
5768         WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
5769             sceneSession->GetWindowId(), sceneSession->GetVisible());
5770         CheckAndNotifyWaterMarkChangedResult();
5771         SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
5772 #ifdef MEMMGR_WINDOW_ENABLE
5773         WLOGD("Notify memMgrWindowInfos changed start");
5774         Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
5775 #endif
5776     }
5777 }
5778 
FindSessionByToken(const sptr<IRemoteObject> & token)5779 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject> &token)
5780 {
5781     sptr<SceneSession> session = nullptr;
5782     auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
5783         if (pair.second == nullptr) {
5784             return false;
5785         }
5786         return pair.second->GetAbilityToken() == token || pair.second->GetSelfToken() == token;
5787     };
5788     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5789     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
5790     if (iter != sceneSessionMap_.end()) {
5791         session = iter->second;
5792     }
5793     return session;
5794 }
5795 
FindSessionByAffinity(std::string affinity)5796 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
5797 {
5798     if (affinity.size() == 0) {
5799         WLOGFI("AbilityInfo affinity is empty");
5800         return nullptr;
5801     }
5802     sptr<SceneSession> session = nullptr;
5803     auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
5804         if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
5805             return false;
5806         }
5807         return pair.second->GetSessionInfo().sessionAffinity == affinity;
5808     };
5809     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5810     auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
5811     if (iter != sceneSessionMap_.end()) {
5812         session = iter->second;
5813     }
5814     return session;
5815 }
5816 
PreloadInLakeApp(const std::string & bundleName)5817 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
5818 {
5819     WLOGFI("run PreloadInLakeApp");
5820     auto iter = collaboratorMap_.find(CollaboratorType::RESERVE_TYPE);
5821     if (iter == collaboratorMap_.end()) {
5822         WLOGFE("Fail to found collaborator with type: RESERVE_TYPE");
5823         return;
5824     }
5825     auto collaborator = iter->second;
5826     if (collaborator != nullptr) {
5827         collaborator->NotifyPreloadAbility(bundleName);
5828     }
5829 }
5830 
PendingSessionToForeground(const sptr<IRemoteObject> & token)5831 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject> &token)
5832 {
5833     WLOGFI("run PendingSessionToForeground");
5834     auto task = [this, &token]() {
5835         auto session = FindSessionByToken(token);
5836         if (session != nullptr) {
5837             return session->PendingSessionToForeground();
5838         }
5839         WLOGFE("fail to find token");
5840         return WSError::WS_ERROR_INVALID_PARAM;
5841     };
5842     return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
5843 }
5844 
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token)5845 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> &token)
5846 {
5847     auto task = [this, &token]() {
5848         auto session = FindSessionByToken(token);
5849         if (session != nullptr) {
5850             return session->PendingSessionToBackgroundForDelegator();
5851         }
5852         WLOGFE("fail to find token");
5853         return WSError::WS_ERROR_INVALID_PARAM;
5854     };
5855     return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
5856 }
5857 
GetFocusSessionToken(sptr<IRemoteObject> & token)5858 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
5859 {
5860     auto task = [this, &token]() {
5861         WLOGFD("run GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
5862         auto sceneSession = GetSceneSession(focusedSessionId_);
5863         if (sceneSession) {
5864             token = sceneSession->GetAbilityToken();
5865             if (token == nullptr) {
5866                 WLOGFE("token is nullptr");
5867                 return WSError::WS_ERROR_INVALID_PARAM;
5868             }
5869             return WSError::WS_OK;
5870         }
5871         return WSError::WS_ERROR_INVALID_PARAM;
5872     };
5873     return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
5874 }
5875 
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)5876 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
5877 {
5878     auto task = [this, persistentId, haveListener]() {
5879         WLOGFI("UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
5880             persistentId, haveListener);
5881         auto sceneSession = GetSceneSession(persistentId);
5882         if (sceneSession == nullptr) {
5883             WLOGFD("sceneSession is nullptr.");
5884             return WSError::WS_DO_NOTHING;
5885         }
5886         if (haveListener) {
5887             avoidAreaListenerSessionSet_.insert(persistentId);
5888             UpdateAvoidArea(persistentId);
5889         } else {
5890             lastUpdatedAvoidArea_.erase(persistentId);
5891             avoidAreaListenerSessionSet_.erase(persistentId);
5892         }
5893         return WSError::WS_OK;
5894     };
5895     return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
5896 }
5897 
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const sptr<SceneSession> & sceneSession,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)5898 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
5899     const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
5900 {
5901     if (sceneSession == nullptr) {
5902         return false;
5903     }
5904     auto iter = lastUpdatedAvoidArea_.find(persistentId);
5905     bool needUpdate = true;
5906 
5907     if (iter != lastUpdatedAvoidArea_.end()) {
5908         auto avoidAreaIter = iter->second.find(avoidAreaType);
5909         if (avoidAreaIter != iter->second.end()) {
5910             needUpdate = avoidAreaIter->second != avoidArea;
5911         } else {
5912             if (avoidArea.isEmptyAvoidArea()) {
5913                 needUpdate = false;
5914                 return needUpdate;
5915             }
5916         }
5917     } else {
5918         if (avoidArea.isEmptyAvoidArea()) {
5919             needUpdate = false;
5920             return needUpdate;
5921         }
5922     }
5923     if (needUpdate ||
5924         avoidAreaType == AvoidAreaType::TYPE_SYSTEM || avoidAreaType == AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
5925         lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
5926         sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
5927     }
5928 
5929     return needUpdate;
5930 }
5931 
UpdateAvoidSessionAvoidArea(WindowType type,bool & needUpdate)5932 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
5933 {
5934     bool ret = true;
5935     AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
5936         AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
5937     for (auto& persistentId : avoidAreaListenerSessionSet_) {
5938         auto sceneSession = GetSceneSession(persistentId);
5939         if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
5940             continue;
5941         }
5942         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
5943         ret = UpdateSessionAvoidAreaIfNeed(
5944             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
5945         needUpdate = needUpdate || ret;
5946     }
5947 
5948     return;
5949 }
5950 
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)5951 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
5952 {
5953     if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
5954         !avoidArea.rightRect_.IsUninitializedRect()) {
5955         return false;
5956     }
5957     if (isVisible) {
5958         if (avoidArea.bottomRect_.IsUninitializedRect() ||
5959             (avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) != sessionBottom)) {
5960             return false;
5961         }
5962     } else if (!avoidArea.bottomRect_.IsUninitializedRect()) {
5963         return false;
5964     }
5965     return true;
5966 }
5967 
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)5968 void SceneSessionManager::UpdateNormalSessionAvoidArea(
5969     const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
5970 {
5971     bool ret = true;
5972     if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
5973         needUpdate = false;
5974         return;
5975     }
5976     if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
5977         WLOGD("id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
5978         needUpdate = false;
5979         return;
5980     }
5981     uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
5982     uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
5983     for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
5984         AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
5985         if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
5986             !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
5987                 sceneSession->GetSessionRect().posY_ + sceneSession->GetSessionRect().height_)) {
5988             continue;
5989         }
5990         ret = UpdateSessionAvoidAreaIfNeed(
5991             persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
5992         needUpdate = needUpdate || ret;
5993     }
5994 
5995     return;
5996 }
5997 
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)5998 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
5999 {
6000     int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
6001     auto sceneSession = GetSceneSession(windowId);
6002     if (sceneSession == nullptr) {
6003         WLOGFW("window not exist: %{public}d", windowId);
6004         return;
6005     }
6006 
6007     wptr<SceneSession> weakSceneSession(sceneSession);
6008     WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
6009     auto task = [weakSceneSession, startMoving]() -> WSError {
6010         auto scnSession = weakSceneSession.promote();
6011         if (scnSession == nullptr) {
6012             WLOGFW("session is null");
6013             return WSError::WS_ERROR_NULLPTR;
6014         }
6015         SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
6016         return WSError::WS_OK;
6017     };
6018     return taskScheduler_->PostAsyncTask(task);
6019 }
6020 
UpdateAvoidArea(const int32_t & persistentId)6021 void SceneSessionManager::UpdateAvoidArea(const int32_t& persistentId)
6022 {
6023     auto task = [this, persistentId]() {
6024         bool needUpdate = false;
6025         auto sceneSession = GetSceneSession(persistentId);
6026         if (sceneSession == nullptr) {
6027             WLOGFD("sceneSession is nullptr.");
6028             return;
6029         }
6030         NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
6031 
6032         WindowType type = sceneSession->GetWindowType();
6033         SessionGravity gravity = SessionGravity::SESSION_GRAVITY_DEFAULT;
6034         uint32_t percent = 0;
6035         if (sceneSession->GetSessionProperty() != nullptr) {
6036             sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
6037         }
6038         if (type == WindowType::WINDOW_TYPE_STATUS_BAR ||
6039             type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
6040             (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
6041             (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM ||
6042             gravity == SessionGravity::SESSION_GRAVITY_DEFAULT))) {
6043             UpdateAvoidSessionAvoidArea(type, needUpdate);
6044         } else {
6045             UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
6046         }
6047         return;
6048     };
6049     taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
6050     return;
6051 }
6052 
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea)6053 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea)
6054 {
6055     WLOGFI("NotifyAINavigationBarShowStatus: isVisible: %{public}u, area{%{public}d,%{public}d,%{public}d,%{public}d}",
6056         isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
6057     auto task = [this, isVisible, barArea]() {
6058         if (isAINavigationBarVisible_ != isVisible || currAINavigationBarArea_ != barArea) {
6059             isAINavigationBarVisible_ = isVisible;
6060             currAINavigationBarArea_ = barArea;
6061             if (!isVisible && !barArea.IsEmpty()) {
6062                 WLOGFD("NotifyAINavigationBarShowStatus: barArea should be empty if invisible");
6063                 currAINavigationBarArea_ = WSRect();
6064             }
6065             WLOGFI("NotifyAINavigationBarShowStatus: enter: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
6066                 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
6067             for (auto persistentId : avoidAreaListenerSessionSet_) {
6068                 auto sceneSession = GetSceneSession(persistentId);
6069                 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
6070                     continue;
6071                 }
6072                 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
6073                 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
6074                     !avoidArea.rightRect_.IsUninitializedRect()) {
6075                     continue;
6076                 }
6077                 if (isVisible && avoidArea.bottomRect_.IsUninitializedRect()) {
6078                     continue;
6079                 }
6080                 WLOGFI("NotifyAINavigationBarShowStatus: persistentId: %{public}d, "
6081                     "{%{public}d,%{public}d,%{public}d,%{public}d}", persistentId,
6082                     avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
6083                     avoidArea.bottomRect_.width_, avoidArea.bottomRect_.height_);
6084                 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
6085                                              AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
6086             }
6087         }
6088     };
6089     taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
6090     return WSError::WS_OK;
6091 }
6092 
GetAINavigationBarArea()6093 WSRect SceneSessionManager::GetAINavigationBarArea()
6094 {
6095     return currAINavigationBarArea_;
6096 }
6097 
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)6098 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
6099 {
6100     auto task = [this, persistentId, haveListener]() {
6101         WLOGFI("UpdateSessionTouchOutsideListener persistentId: %{public}d haveListener:%{public}d",
6102             persistentId, haveListener);
6103         auto sceneSession = GetSceneSession(persistentId);
6104         if (sceneSession == nullptr) {
6105             WLOGFD("sceneSession is nullptr.");
6106             return WSError::WS_DO_NOTHING;
6107         }
6108         if (haveListener) {
6109             touchOutsideListenerSessionSet_.insert(persistentId);
6110         } else {
6111             touchOutsideListenerSessionSet_.erase(persistentId);
6112         }
6113         return WSError::WS_OK;
6114     };
6115     return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
6116 }
6117 
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)6118 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
6119 {
6120     auto task = [this, persistentId, haveListener]() -> WSError {
6121         WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
6122             persistentId, haveListener);
6123         auto sceneSession = GetSceneSession(persistentId);
6124         if (sceneSession == nullptr) {
6125             WLOGFD("sceneSession is nullptr.");
6126             return WSError::WS_DO_NOTHING;
6127         }
6128         if (haveListener) {
6129             windowVisibilityListenerSessionSet_.insert(persistentId);
6130             sceneSession->NotifyWindowVisibility();
6131         } else {
6132             windowVisibilityListenerSessionSet_.erase(persistentId);
6133         }
6134         return WSError::WS_OK;
6135     };
6136     return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
6137 }
6138 
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)6139 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
6140 {
6141     processVirtualPixelRatioChangeFunc_ = func;
6142     WLOGFI("SetVirtualPixelRatioChangeListener");
6143 }
6144 
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)6145 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
6146     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
6147 {
6148     if (displayInfo == nullptr) {
6149         WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
6150         return;
6151     }
6152     auto task = [this, displayInfo]() {
6153         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6154         if (processVirtualPixelRatioChangeFunc_ != nullptr &&
6155             displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
6156             Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
6157                 displayInfo->GetWidth(), displayInfo->GetHeight()
6158             };
6159             processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
6160         }
6161         for (const auto &item : sceneSessionMap_) {
6162             auto scnSession = item.second;
6163             if (scnSession == nullptr) {
6164                 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
6165                 continue;
6166             }
6167             SessionInfo sessionInfo = scnSession->GetSessionInfo();
6168             if (sessionInfo.isSystem_) {
6169                 continue;
6170             }
6171             if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
6172                 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
6173                 scnSession->UpdateDensity();
6174                 WLOGFD("UpdateDensity name=%{public}s, persistendId=%{public}d, winType=%{public}d, "
6175                     "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
6176                     scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
6177             }
6178         }
6179         return WSError::WS_OK;
6180     };
6181     taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
6182 }
6183 
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)6184 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
6185     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
6186 {
6187     if (displayInfo == nullptr) {
6188         WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
6189         return;
6190     }
6191     auto task = [this, displayInfo]() {
6192         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6193         for (const auto &item : sceneSessionMap_) {
6194             auto scnSession = item.second;
6195             if (scnSession == nullptr) {
6196                 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
6197                 continue;
6198             }
6199             if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
6200                 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
6201                 scnSession->UpdateRotationAvoidArea();
6202                 WLOGFD("UpdateRotationAvoidArea name=%{public}s, persistendId=%{public}d, winType=%{public}d, "
6203                     "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
6204                     scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
6205             }
6206         }
6207         return WSError::WS_OK;
6208     };
6209     taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
6210 }
6211 
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)6212 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
6213     const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
6214 {
6215     WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
6216     switch (type) {
6217         case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
6218             SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
6219                 displayInfo, displayInfoMap, type);
6220             break;
6221         }
6222         case DisplayStateChangeType::UPDATE_ROTATION: {
6223             SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
6224                 displayInfo, displayInfoMap, type);
6225             break;
6226         }
6227         default:
6228             return;
6229     }
6230 }
6231 
OnScreenshot(DisplayId displayId)6232 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
6233 {
6234     SceneSessionManager::GetInstance().OnScreenshot(displayId);
6235 }
6236 
OnScreenshot(DisplayId displayId)6237 void SceneSessionManager::OnScreenshot(DisplayId displayId)
6238 {
6239     auto task = [this, displayId]() {
6240         auto sceneSession = GetSceneSession(focusedSessionId_);
6241         if (sceneSession) {
6242             sceneSession->NotifyScreenshot();
6243         }
6244     };
6245     taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
6246 }
6247 
ClearSession(int32_t persistentId)6248 WSError SceneSessionManager::ClearSession(int32_t persistentId)
6249 {
6250     WLOGFI("run ClearSession with persistentId: %{public}d", persistentId);
6251     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6252         WLOGFE("The caller is not system-app, can not use system-api");
6253         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6254     }
6255     if (!SessionPermission::VerifySessionPermission()) {
6256         WLOGFE("The caller has not permission granted");
6257         return WSError::WS_ERROR_INVALID_PERMISSION;
6258     }
6259     auto task = [this, persistentId]() {
6260         sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6261         return ClearSession(sceneSession);
6262     };
6263     taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
6264     return WSError::WS_OK;
6265 }
6266 
ClearSession(sptr<SceneSession> sceneSession)6267 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
6268 {
6269     WLOGFI("run ClearSession");
6270     if (sceneSession == nullptr) {
6271         WLOGFE("sceneSession is nullptr");
6272         return WSError::WS_ERROR_INVALID_SESSION;
6273     }
6274     if (!IsSessionClearable(sceneSession)) {
6275         WLOGFI("sceneSession cannot be clear, persistentId %{public}d.", sceneSession->GetPersistentId());
6276         return WSError::WS_ERROR_INVALID_SESSION;
6277     }
6278     const WSError& errCode = sceneSession->Clear();
6279     return errCode;
6280 }
6281 
ClearAllSessions()6282 WSError SceneSessionManager::ClearAllSessions()
6283 {
6284     WLOGFI("run ClearAllSessions");
6285     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6286         WLOGFE("The caller is not system-app, can not use system-api");
6287         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6288     }
6289     if (!SessionPermission::VerifySessionPermission()) {
6290         WLOGFE("The caller has not permission granted");
6291         return WSError::WS_ERROR_INVALID_PERMISSION;
6292     }
6293     auto task = [this]() {
6294         std::vector<sptr<SceneSession>> sessionVector;
6295         GetAllClearableSessions(sessionVector);
6296         for (uint32_t i = 0; i < sessionVector.size(); i++) {
6297             ClearSession(sessionVector[i]);
6298         }
6299         return WSError::WS_OK;
6300     };
6301     taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
6302     return WSError::WS_OK;
6303 }
6304 
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)6305 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
6306 {
6307     WLOGFI("run GetAllClearableSessions");
6308     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6309     for (const auto &item : sceneSessionMap_) {
6310         auto scnSession = item.second;
6311         if (IsSessionClearable(scnSession)) {
6312             sessionVector.push_back(scnSession);
6313         }
6314     }
6315 }
6316 
LockSession(int32_t sessionId)6317 WSError SceneSessionManager::LockSession(int32_t sessionId)
6318 {
6319     WLOGFI("run LockSession with persistentId: %{public}d", sessionId);
6320     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6321         WLOGFE("The caller is not system-app, can not use system-api");
6322         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6323     }
6324     if (!SessionPermission::VerifySessionPermission()) {
6325         WLOGFE("The caller has not permission granted");
6326         return WSError::WS_ERROR_INVALID_PERMISSION;
6327     }
6328     auto task = [this, sessionId]() {
6329         auto sceneSession = GetSceneSession(sessionId);
6330         if (sceneSession == nullptr) {
6331             WLOGFE("can not find sceneSession, sessionId:%{public}d", sessionId);
6332             return WSError::WS_ERROR_INVALID_PARAM;
6333         }
6334         sceneSession->SetSessionInfoLockedState(true);
6335         return WSError::WS_OK;
6336     };
6337     return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
6338 }
6339 
UnlockSession(int32_t sessionId)6340 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
6341 {
6342     WLOGFI("run UnlockSession with persistentId: %{public}d", sessionId);
6343     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6344         WLOGFE("The caller is not system-app, can not use system-api");
6345         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6346     }
6347     if (!SessionPermission::VerifySessionPermission()) {
6348         WLOGFE("The caller has not permission granted");
6349         return WSError::WS_ERROR_INVALID_PERMISSION;
6350     }
6351     auto task = [this, sessionId]() {
6352         auto sceneSession = GetSceneSession(sessionId);
6353         if (sceneSession == nullptr) {
6354             WLOGFE("can not find sceneSession, sessionId:%{public}d", sessionId);
6355             return WSError::WS_ERROR_INVALID_PARAM;
6356         }
6357         sceneSession->SetSessionInfoLockedState(false);
6358         return WSError::WS_OK;
6359     };
6360     return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
6361 }
6362 
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)6363 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
6364 {
6365     WLOGFI("run MoveSessionsToForeground");
6366     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6367         WLOGFE("The caller is not system-app, can not use system-api");
6368         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6369     }
6370     if (!SessionPermission::VerifySessionPermission()) {
6371         WLOGFE("The caller has not permission granted");
6372         return WSError::WS_ERROR_INVALID_PERMISSION;
6373     }
6374 
6375     return WSError::WS_OK;
6376 }
6377 
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)6378 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
6379     std::vector<int32_t>& result)
6380 {
6381     WLOGFI("run MoveSessionsToBackground");
6382     if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6383         WLOGFE("The caller is not system-app, can not use system-api");
6384         return WSError::WS_ERROR_NOT_SYSTEM_APP;
6385     }
6386     if (!SessionPermission::VerifySessionPermission()) {
6387         WLOGFE("The caller has not permission granted");
6388         return WSError::WS_ERROR_INVALID_PERMISSION;
6389     }
6390 
6391     result.insert(result.end(), sessionIds.begin(), sessionIds.end());
6392     return WSError::WS_OK;
6393 }
6394 
IsSessionClearable(sptr<SceneSession> scnSession)6395 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
6396 {
6397     if (scnSession == nullptr) {
6398         WLOGFI("scnSession is nullptr");
6399         return false;
6400     }
6401     SessionInfo sessionInfo = scnSession->GetSessionInfo();
6402     if (sessionInfo.abilityInfo == nullptr) {
6403         WLOGFI("scnSession abilityInfo is nullptr");
6404         return false;
6405     }
6406     if (sessionInfo.abilityInfo->excludeFromMissions) {
6407         WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
6408         return false;
6409     }
6410     if (sessionInfo.abilityInfo->unclearableMission) {
6411         WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
6412         return false;
6413     }
6414     if (sessionInfo.isSystem_) {
6415         WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
6416         return false;
6417     }
6418     if (sessionInfo.lockedState) {
6419         WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
6420         return false;
6421     }
6422 
6423     return true;
6424 }
6425 
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)6426 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
6427     const sptr<AAFwk::IAbilityManagerCollaborator> &impl)
6428 {
6429     WLOGFI("RegisterIAbilityManagerCollaborator with type : %{public}d", type);
6430     auto isSaCall = SessionPermission::IsSACalling();
6431     auto callingUid = IPCSkeleton::GetCallingUid();
6432     if (!isSaCall || (callingUid != BROKER_UID && callingUid != BROKER_RESERVE_UID)) {
6433         WLOGFE("The interface only support for broker");
6434         return WSError::WS_ERROR_INVALID_PERMISSION;
6435     }
6436     if (!CheckCollaboratorType(type)) {
6437         WLOGFW("collaborator register failed, invalid type.");
6438         return WSError::WS_ERROR_INVALID_TYPE;
6439     }
6440     {
6441         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
6442         collaboratorMap_[type] = impl;
6443     }
6444     return WSError::WS_OK;
6445 }
6446 
UnregisterIAbilityManagerCollaborator(int32_t type)6447 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
6448 {
6449     WLOGFI("UnregisterIAbilityManagerCollaborator with type : %{public}d", type);
6450     auto isSaCall = SessionPermission::IsSACalling();
6451     auto callingUid = IPCSkeleton::GetCallingUid();
6452     if (!isSaCall || (callingUid != BROKER_UID && callingUid != BROKER_RESERVE_UID)) {
6453         WLOGFE("The interface only support for broker");
6454         return WSError::WS_ERROR_INVALID_PERMISSION;
6455     }
6456     if (!CheckCollaboratorType(type)) {
6457         WLOGFE("collaborator unregister failed, invalid type.");
6458         return WSError::WS_ERROR_INVALID_TYPE;
6459     }
6460     {
6461         std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
6462         collaboratorMap_.erase(type);
6463     }
6464     return WSError::WS_OK;
6465 }
6466 
ProcessPiPSessionForeground(const sptr<SceneSession> sceneSession)6467 void SceneSessionManager::ProcessPiPSessionForeground(const sptr<SceneSession> sceneSession)
6468 {
6469     if (sceneSession == nullptr) {
6470         WLOGFE("pip window not found");
6471         return;
6472     }
6473     WLOGFD("start pip rect");
6474     sceneSession->UpdatePiPRect(0, 0, PiPRectUpdateReason::REASON_PIP_START_WINDOW);
6475 }
6476 
RecoveryPullPiPMainWindow(const int32_t & persistentId,const Rect & rect)6477 WSError SceneSessionManager::RecoveryPullPiPMainWindow(const int32_t& persistentId, const Rect& rect)
6478 {
6479     auto scnSession = GetSceneSession(persistentId);
6480     if (scnSession == nullptr) {
6481         WLOGFE("scnSession is nullptr, persistentId: %{public}d", persistentId);
6482         return WSError::WS_ERROR_NULLPTR;
6483     }
6484     if (!WindowHelper::IsPipWindow(scnSession->GetWindowType())) {
6485         WLOGFE("not pip window");
6486         return WSError::WS_DO_NOTHING;
6487     }
6488     if (!showPiPMainWindowFunc_) {
6489         WLOGFE("showPiPMainWindowFunc_ init error, persistentId: %{public}d", persistentId);
6490         return WSError::WS_DO_NOTHING;
6491     }
6492     auto task = [this, scnSession, rect]() {
6493         showPiPMainWindowFunc_(scnSession->GetParentPersistentId());
6494         WSRect rectPos = SessionHelper::TransferToWSRect(rect);
6495         scnSession->UpdateSessionRect(rectPos, SizeChangeReason::RECOVER);
6496         return WSError::WS_OK;
6497     };
6498     taskScheduler_->PostAsyncTask(task, "RecoveryPullPiPMainWindow");
6499     return WSError::WS_OK;
6500 }
6501 
CheckCollaboratorType(int32_t type)6502 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
6503 {
6504     if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
6505         WLOGFD("type is invalid");
6506         return false;
6507     }
6508     return true;
6509 }
6510 
CheckIfReuseSession(SessionInfo & sessionInfo)6511 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
6512 {
6513     auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
6514         sessionInfo.moduleName_);
6515     if (abilityInfo == nullptr) {
6516         WLOGFE("CheckIfReuseSession abilityInfo is nullptr!");
6517         return BrokerStates::BROKER_UNKOWN;
6518     }
6519     sessionInfo.abilityInfo = abilityInfo;
6520     int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
6521     if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
6522         collaboratorType = CollaboratorType::RESERVE_TYPE;
6523     } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
6524         collaboratorType = CollaboratorType::OTHERS_TYPE;
6525     }
6526     if (!CheckCollaboratorType(collaboratorType)) {
6527         WLOGFW("CheckIfReuseSession not collaborator!");
6528         return BrokerStates::BROKER_UNKOWN;
6529     }
6530     BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
6531     sessionInfo.collaboratorType_ = collaboratorType;
6532     sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
6533     if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
6534         WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
6535         sessionInfo.reuse = true;
6536     } else {
6537         sessionInfo.reuse = false;
6538     }
6539     WLOGFI("CheckIfReuseSession end, affinity %{public}s type %{public}d reuse %{public}d",
6540         sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
6541     return resultValue;
6542 }
6543 
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)6544 BrokerStates SceneSessionManager::NotifyStartAbility(
6545     int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
6546 {
6547     WLOGFI("run NotifyStartAbility type %{public}d param id %{public}d", collaboratorType, persistentId);
6548     auto iter = collaboratorMap_.find(collaboratorType);
6549     if (iter == collaboratorMap_.end()) {
6550         WLOGFI("Fail to found collaborator with type: %{public}d", collaboratorType);
6551         return BrokerStates::BROKER_UNKOWN;
6552     }
6553     if (sessionInfo.want == nullptr) {
6554         WLOGFI("sessionInfo.want is nullptr, init");
6555         sessionInfo.want = std::make_shared<AAFwk::Want>();
6556         sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
6557             sessionInfo.moduleName_);
6558     }
6559     auto collaborator = iter->second;
6560     auto accessTokenIDEx = sessionInfo.callingTokenId_;
6561     if (collaborator != nullptr) {
6562         containerStartAbilityTime = std::chrono::duration_cast<std::chrono::milliseconds>(
6563             std::chrono::system_clock::now().time_since_epoch()).count();
6564 
6565         std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
6566         if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
6567             WLOGFI("NotifyStartAbility affinity exit %{public}s.", affinity.c_str());
6568             return BrokerStates::BROKER_UNKOWN;
6569         }
6570         sessionInfo.want->SetParam("oh_persistentId", persistentId);
6571         int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
6572             currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
6573         WLOGFI("NotifyStartAbility ret: %{public}d", ret);
6574         if (ret == 0) {
6575             return BrokerStates::BROKER_STARTED;
6576         } else {
6577             return BrokerStates::BROKER_NOT_START;
6578         }
6579     }
6580     return BrokerStates::BROKER_UNKOWN;
6581 }
6582 
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)6583 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
6584 {
6585     WLOGFI("run NotifySessionCreate");
6586     if (sceneSession == nullptr) {
6587         WLOGFE("sceneSession is nullptr");
6588         return;
6589     }
6590     if (sessionInfo.want == nullptr) {
6591         WLOGFI("sessionInfo.want is nullptr");
6592         return;
6593     }
6594     auto iter = collaboratorMap_.find(sceneSession->GetCollaboratorType());
6595     if (iter == collaboratorMap_.end()) {
6596         WLOGFI("Fail to found collaborator with type: %{public}d", sceneSession->GetCollaboratorType());
6597         return;
6598     }
6599     auto collaborator = iter->second;
6600     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6601     sceneSession->SetSelfToken(abilitySessionInfo->sessionToken);
6602     abilitySessionInfo->want = *(sessionInfo.want);
6603     if (collaborator != nullptr) {
6604         int32_t missionId = abilitySessionInfo->persistentId;
6605         std::string bundleName = sessionInfo.bundleName_;
6606         int64_t timestamp = containerStartAbilityTime;
6607         WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
6608 
6609         collaborator->NotifyMissionCreated(abilitySessionInfo);
6610     }
6611 }
6612 
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)6613 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
6614     sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
6615 {
6616     WLOGFI("run NotifyLoadAbility");
6617     auto iter = collaboratorMap_.find(collaboratorType);
6618     if (iter == collaboratorMap_.end()) {
6619         WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
6620         return;
6621     }
6622     auto collaborator = iter->second;
6623     if (collaborator != nullptr) {
6624         collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
6625     }
6626 }
6627 
6628 
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)6629 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
6630 {
6631     WLOGFI("run NotifyUpdateSessionInfo");
6632     if (sceneSession == nullptr) {
6633         WLOGFE("sceneSession is nullptr");
6634         return;
6635     }
6636     auto iter = collaboratorMap_.find(sceneSession->GetCollaboratorType());
6637     if (iter == collaboratorMap_.end()) {
6638         WLOGFE("Fail to found collaborator with type: %{public}d", sceneSession->GetCollaboratorType());
6639         return;
6640     }
6641     auto collaborator = iter->second;
6642     auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6643     if (collaborator != nullptr) {
6644         collaborator->UpdateMissionInfo(abilitySessionInfo);
6645     }
6646 }
6647 
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)6648 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
6649 {
6650     WLOGFI("run NotifyMoveSessionToForeground");
6651     auto iter = collaboratorMap_.find(collaboratorType);
6652     if (iter == collaboratorMap_.end()) {
6653         WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
6654         return;
6655     }
6656     auto collaborator = iter->second;
6657     if (collaborator != nullptr) {
6658         collaborator->NotifyMoveMissionToForeground(persistentId);
6659     }
6660 }
6661 
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)6662 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
6663 {
6664     WLOGFI("run NotifyClearSession with persistentId %{public}d", persistentId);
6665     auto iter = collaboratorMap_.find(collaboratorType);
6666     if (iter == collaboratorMap_.end()) {
6667         WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
6668         return;
6669     }
6670     auto collaborator = iter->second;
6671     if (collaborator != nullptr) {
6672         collaborator->NotifyClearMission(persistentId);
6673     }
6674 }
6675 
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)6676 void SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
6677 {
6678     WLOGFI("run PreHandleCollaborator");
6679     if (sceneSession == nullptr) {
6680         return;
6681     }
6682     std::string sessionAffinity;
6683     WLOGFI("try to run NotifyStartAbility and NotifySessionCreate");
6684     if (sceneSession->GetSessionInfo().want != nullptr) {
6685         sessionAffinity = sceneSession->GetSessionInfo().want
6686             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
6687     }
6688     if (sessionAffinity.empty()) {
6689         WLOGFI("PreHandleCollaborator sessionAffinity: %{public}s", sessionAffinity.c_str());
6690         BrokerStates notifyReturn = NotifyStartAbility(
6691             sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
6692         if (notifyReturn != BrokerStates::BROKER_STARTED) {
6693             WLOGFI("PreHandleCollaborator cant notify");
6694             return;
6695         }
6696 
6697     }
6698     if (sceneSession->GetSessionInfo().want != nullptr) {
6699         WLOGFI("broker persistentId: %{public}d",
6700             sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0));
6701         sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
6702             ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
6703         WLOGFI("affinity: %{public}s", sceneSession->GetSessionInfo().sessionAffinity.c_str());
6704     } else {
6705         WLOGFI("sceneSession->GetSessionInfo().want is nullptr");
6706     }
6707     NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
6708     sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
6709 }
6710 
AddWindowDragHotArea(int32_t type,WSRect & area)6711 void SceneSessionManager::AddWindowDragHotArea(int32_t type, WSRect& area)
6712 {
6713     WLOGFI("run AddWindowDragHotArea, type: %{public}d,posX: %{public}d,posY: %{public}d,width: %{public}d,"
6714         "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
6715     SceneSession::windowDragHotAreaMap_.insert({type, area});
6716 }
6717 
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)6718 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
6719 {
6720     auto task = [this, persistentId, isMaximize]() -> WSError {
6721         WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
6722         auto sceneSession = GetSceneSession(persistentId);
6723         if (sceneSession == nullptr) {
6724             WLOGFE("could not find window, persistentId:%{public}d", persistentId);
6725             return WSError::WS_ERROR_INVALID_WINDOW;
6726         }
6727         sceneSession->UpdateMaximizeMode(isMaximize);
6728         return WSError::WS_OK;
6729     };
6730     taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
6731     return WSError::WS_OK;
6732 }
6733 
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)6734 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
6735 {
6736     auto scnSession = GetSceneSession(persistentId);
6737     if (!scnSession) {
6738         WLOGFE("session is nullptr");
6739         return WSError::WS_ERROR_INVALID_WINDOW;
6740     }
6741     auto fromScreenId = scnSession->GetSessionInfo().screenId_;
6742     scnSession->SetScreenId(screenId);
6743     if (!scnSession->GetSessionProperty()) {
6744         WLOGFE("Property is null, synchronous screenId failed");
6745         return WSError::WS_ERROR_NULLPTR;
6746     }
6747     scnSession->GetSessionProperty()->SetDisplayId(screenId);
6748     WLOGFD("Session move display %{public}" PRIu64" from %{public}" PRIu64"", screenId, fromScreenId);
6749     NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
6750     return WSError::WS_OK;
6751 }
6752 
OnImmersiveStateChange(bool & immersive)6753 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
6754 {
6755     immersive = SceneSessionManager::GetInstance().UpdateImmersiveState();
6756 }
6757 
UpdateImmersiveState()6758 bool SceneSessionManager::UpdateImmersiveState()
6759 {
6760     std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6761     for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
6762         auto sceneSession = item->second;
6763         if (sceneSession == nullptr) {
6764             WLOGFE("Session is nullptr");
6765             continue;
6766         }
6767         if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6768             continue;
6769         }
6770         auto state = sceneSession->GetSessionState();
6771         if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6772             continue;
6773         }
6774         if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
6775             continue;
6776         }
6777         auto property = sceneSession->GetSessionProperty();
6778         if (property == nullptr) {
6779             WLOGFE("Property is nullptr");
6780             continue;
6781         }
6782         auto sysBarProperty = property->GetSystemBarProperty();
6783         if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
6784             WLOGFD("Current window is immersive");
6785             return true;
6786         } else {
6787             WLOGFD("Current window is not immersive");
6788             break;
6789         }
6790     }
6791     return false;
6792 }
6793 
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)6794 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
6795     bool withAnimation)
6796 {
6797     session->NotifySessionForeground(reason, withAnimation);
6798 }
6799 
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)6800 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
6801     bool withAnimation, bool isFromInnerkits)
6802 {
6803     session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
6804 }
6805 
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)6806 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
6807 {
6808     auto sceneSession = GetSceneSession(persistentId);
6809     if (sceneSession == nullptr) {
6810         WLOGFE("could not find window, persistentId:%{public}d", persistentId);
6811         return WSError::WS_ERROR_INVALID_WINDOW;
6812     }
6813     return sceneSession->UpdateTitleInTargetPos(isShow, height);
6814 }
6815 
GetSceneSessionMap()6816 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
6817 {
6818     std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
6819     {
6820         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6821         retSceneSessionMap = sceneSessionMap_;
6822     }
6823     EraseIf(retSceneSessionMap, [this](const auto& pair) {
6824         if (pair.second == nullptr) {
6825             return true;
6826         }
6827 
6828         if (pair.second->IsSystemInput()) {
6829             return false;
6830         } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
6831             return false;
6832         }
6833         if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
6834             return true;
6835         }
6836         return false;
6837     });
6838     return retSceneSessionMap;
6839 }
6840 
NotifyUpdateRectAfterLayout()6841 void SceneSessionManager::NotifyUpdateRectAfterLayout()
6842 {
6843     auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
6844     std::shared_ptr<RSTransaction> rsTransaction = nullptr;
6845     if (transactionController) {
6846         rsTransaction = transactionController->GetRSTransaction();
6847     }
6848     auto task = [this, rsTransaction]() {
6849         std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6850         for (const auto& iter: sceneSessionMap_) {
6851             auto sceneSession = iter.second;
6852             if (sceneSession && sceneSession->IsDirtyWindow()) {
6853                 sceneSession->NotifyClientToUpdateRect(rsTransaction);
6854             }
6855         }
6856     };
6857     // need sync task since animation transcation need
6858     return taskScheduler_->PostAsyncTask(task, "NotifyUpdateRectAfterLayout");
6859 }
6860 
RaiseWindowToTop(int32_t persistentId)6861 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
6862 {
6863     WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
6864     auto isSaCall = SessionPermission::IsSACalling();
6865     if (!isSaCall) {
6866         WLOGFE("The interface only support for sa call");
6867         return WSError::WS_ERROR_INVALID_PERMISSION;
6868     }
6869     auto task = [this, persistentId]() {
6870         auto sceneSession = GetSceneSession(persistentId);
6871         if (sceneSession == nullptr) {
6872             WLOGFE("session is nullptr");
6873             return WSError::WS_ERROR_INVALID_SESSION;
6874         }
6875         if (!IsSessionVisible(sceneSession)) {
6876             WLOGFD("session is not visible!");
6877             return WSError::WS_DO_NOTHING;
6878         }
6879         RequestSessionFocus(persistentId, true);
6880         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
6881             sceneSession->RaiseToAppTop();
6882         }
6883         if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
6884             sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
6885             WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
6886             sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
6887         }
6888         if (sceneSession == nullptr) {
6889             WLOGFE("parent session is nullptr");
6890             return WSError::WS_ERROR_INVALID_SESSION;
6891         }
6892         if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6893             sceneSession->NotifyClick();
6894             return WSError::WS_OK;
6895         } else {
6896             WLOGFE("session is not app main window!");
6897             return WSError::WS_ERROR_INVALID_SESSION;
6898         }
6899     };
6900     taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
6901     return WSError::WS_OK;
6902 }
6903 
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)6904 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
6905 {
6906     WLOGI("run ShiftAppWindowFocus, form id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
6907     if (sourcePersistentId != focusedSessionId_) {
6908         WLOGE("source session need be focused");
6909         return WSError::WS_ERROR_INVALID_OPERATION;
6910     }
6911     if (targetPersistentId == focusedSessionId_) {
6912         WLOGE("target session has been focused");
6913         return WSError::WS_DO_NOTHING;
6914     }
6915     sptr<SceneSession> sourceSession = nullptr;
6916     WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
6917     if (ret != WSError::WS_OK) {
6918         return ret;
6919     }
6920     sptr<SceneSession> targetSession = nullptr;
6921     ret = GetAppMainSceneSession(targetSession, targetPersistentId);
6922     if (ret != WSError::WS_OK) {
6923         return ret;
6924     }
6925     if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
6926         WLOGE("verify bundle name failed, source bundle name is %{public}s but target bundle name is %{public}s)",
6927             sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
6928         return WSError::WS_ERROR_INVALID_CALLING;
6929     }
6930     if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
6931         return WSError::WS_ERROR_INVALID_CALLING;
6932     }
6933     targetSession->NotifyClick();
6934     return RequestSessionFocus(targetPersistentId, false);
6935 }
6936 
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)6937 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
6938 {
6939     sceneSession = GetSceneSession(persistentId);
6940     if (sceneSession == nullptr) {
6941         WLOGE("session(id: %{public}d) is nullptr", persistentId);
6942         return WSError::WS_ERROR_INVALID_SESSION;
6943     }
6944     if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6945         if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
6946             WLOGE("session(id: %{public}d) is not main window or sub window", persistentId);
6947             return WSError::WS_ERROR_INVALID_CALLING;
6948         }
6949         sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
6950         if (sceneSession == nullptr) {
6951             WLOGE("session(id: %{public}d) parent is nullptr", persistentId);
6952             return WSError::WS_ERROR_INVALID_SESSION;
6953         }
6954     }
6955     return WSError::WS_OK;
6956 }
6957 
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)6958 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
6959     const float scaleParam)
6960 {
6961     auto sceneSession = GetSceneSession(persistentId);
6962     if (!sceneSession) {
6963         WLOGFE("get scene session is nullptr");
6964         return nullptr;
6965     }
6966 
6967     wptr<SceneSession> weakSceneSession(sceneSession);
6968     auto task = [this, persistentId, scaleParam, weakSceneSession]() {
6969         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
6970         auto scnSession = weakSceneSession.promote();
6971         std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
6972         if (scnSession == nullptr) {
6973             WLOGFE("session is nullptr");
6974             return pixelMap;
6975         }
6976 
6977         if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
6978             scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
6979             pixelMap = scnSession->Snapshot(scaleParam);
6980         }
6981         if (!pixelMap) {
6982             WLOGFI("get local snapshot pixelmap start");
6983             pixelMap = scnSession->GetSnapshotPixelMap (snapshotScale_, scaleParam);
6984         }
6985         return pixelMap;
6986     };
6987     return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
6988 }
6989 
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)6990 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> &debugInfos)
6991 {
6992     WLOGFI("AppAnrListener OnAppDebugStarted");
6993     if (debugInfos.empty()) {
6994         WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
6995         return;
6996     }
6997     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
6998 }
6999 
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)7000 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> &debugInfos)
7001 {
7002     WLOGFI("AppAnrListener OnAppDebugStoped");
7003     if (debugInfos.empty()) {
7004         WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
7005         return;
7006     }
7007     DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
7008 }
7009 
FlushWindowInfoToMMI()7010 void SceneSessionManager::FlushWindowInfoToMMI()
7011 {
7012     auto task = []()-> WSError {
7013         HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
7014         SceneInputManager::GetInstance().FlushDisplayInfoToMMI();
7015         return WSError::WS_OK;
7016     };
7017     return taskScheduler_->PostAsyncTask(task);
7018 }
7019 
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)7020 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
7021 {
7022     if (!SessionPermission::IsSystemCalling()) {
7023         WLOGFE("GetVisibilityWindowInfo permission denied!");
7024         return WMError::WM_ERROR_NOT_SYSTEM_APP;
7025     }
7026     auto task = [this, &infos]() {
7027         for (auto [surfaceId, _] : lastVisibleData_) {
7028             sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7029             if (session == nullptr) {
7030                 continue;
7031             }
7032             infos.emplace_back(new WindowVisibilityInfo(session->GetWindowId(), session->GetCallingPid(),
7033                 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType()));
7034         }
7035         return WMError::WM_OK;
7036     };
7037     return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
7038 }
7039 
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)7040 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
7041     const std::string taskName, const int delayTime)
7042 {
7043     taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
7044 }
7045 
HideNonSecureWindows(bool shouldHide)7046 WSError SceneSessionManager::HideNonSecureWindows(bool shouldHide)
7047 {
7048     WLOGFI("HideNonSecureWindows, shouldHide %{public}u", shouldHide);
7049     if (!SessionPermission::IsSystemCalling()) {
7050         WLOGFE("HideNonSecureWindows permission denied!");
7051         return WSError::WS_ERROR_NOT_SYSTEM_APP;
7052     }
7053     auto task = [this, shouldHide]() {
7054         for (const auto& item: nonSystemFloatSceneSessionMap_) {
7055             auto session = item.second;
7056             if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
7057                 session->NotifyForceHideChange(shouldHide);
7058                 WLOGFI("HideNonSecureWindows name=%{public}s, persistendId=%{public}d",
7059                        session->GetWindowName().c_str(), item.first);
7060             }
7061         }
7062         return WSError::WS_OK;
7063     };
7064     return taskScheduler_->PostSyncTask(task);
7065 }
7066 } // namespace OHOS::Rosen
7067