1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "session_manager/include/scene_session_manager.h"
17
18 #include <ability_context.h>
19 #include <ability_manager_client.h>
20 #include <application_context.h>
21 #include <bundlemgr/launcher_service.h>
22 #include <hisysevent.h>
23 #include <parameters.h>
24 #include <hitrace_meter.h>
25 #include "parameter.h"
26 #include "publish/scb_dump_subscriber.h"
27
28 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
29 #include <display_power_mgr_client.h>
30 #endif
31
32 #ifdef POWER_MANAGER_ENABLE
33 #include <power_mgr_client.h>
34 #endif
35
36 #ifdef RES_SCHED_ENABLE
37 #include "res_type.h"
38 #include "res_sched_client.h"
39 #endif
40 #include "scene_system_ability_listener.h"
41
42 #include "anr_manager.h"
43 #include "color_parser.h"
44 #include "common/include/session_permission.h"
45 #include "display_manager.h"
46 #include "scene_input_manager.h"
47 #include "session/host/include/main_session.h"
48 #include "session/host/include/scb_system_session.h"
49 #include "session/host/include/scene_persistent_storage.h"
50 #include "session/host/include/session_utils.h"
51 #include "session/host/include/sub_session.h"
52 #include "session_helper.h"
53 #include "window_helper.h"
54 #include "screen_session_manager/include/screen_session_manager_client.h"
55 #include "singleton_container.h"
56 #include "xcollie/watchdog.h"
57 #include "session_manager_agent_controller.h"
58 #include "distributed_client.h"
59 #include "softbus_bus_center.h"
60 #include "perform_reporter.h"
61 #include "anr_manager.h"
62 #include "dms_reporter.h"
63 #include "res_sched_client.h"
64 #include "anomaly_detection.h"
65 #ifdef MEMMGR_WINDOW_ENABLE
66 #include "mem_mgr_client.h"
67 #include "mem_mgr_window_info.h"
68 #endif
69
70 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
71 #include "sec_comp_enhance_kit.h"
72 #endif
73
74 #ifdef IMF_ENABLE
75 #include <input_method_controller.h>
76 #endif // IMF_ENABLE
77
78 namespace OHOS::Rosen {
79 namespace {
80 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
81 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
82 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
83 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
84 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
85 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
86
87 constexpr const char* KEY_SESSION_ID = "com.ohos.param.sessionId";
88 constexpr uint32_t MAX_BRIGHTNESS = 255;
89 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
90 constexpr int32_t DEFAULT_USERID = -1;
91 constexpr int32_t SCALE_DIMENSION = 2;
92 constexpr int32_t TRANSLATE_DIMENSION = 2;
93 constexpr int32_t ROTAION_DIMENSION = 4;
94 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
95 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
96 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
97 const std::string EMPTY_DEVICE_ID = "";
98 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
99
100 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
101 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
102 constexpr int VALUE_MAX_WIDTH = 5;
103 constexpr int MAX_RESEND_TIMES = 6;
104 constexpr int ORIEN_MAX_WIDTH = 12;
105 constexpr int OFFSET_MAX_WIDTH = 8;
106 constexpr int SCALE_MAX_WIDTH = 8;
107 constexpr int PID_MAX_WIDTH = 8;
108 constexpr int PARENT_ID_MAX_WIDTH = 6;
109 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
110 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
111 const std::string ARG_DUMP_ALL = "-a";
112 const std::string ARG_DUMP_WINDOW = "-w";
113 const std::string ARG_DUMP_SCREEN = "-s";
114 const std::string ARG_DUMP_DISPLAY = "-d";
115 const std::string ARG_DUMP_PIPLINE = "-p";
116 const std::string ARG_DUMP_SCB = "-b";
117 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
118 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
119 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
120
121 static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
122
123 static std::shared_ptr<ScbDumpSubscriber> g_scbSubscriber(nullptr);
124
GetCurrentTime()125 std::string GetCurrentTime()
126 {
127 struct timespec tn;
128 clock_gettime(CLOCK_REALTIME, &tn);
129 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
130 static_cast<uint64_t>(tn.tv_nsec);
131 return std::to_string(uTime);
132 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)133 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
134 {
135 return a.first < b.first;
136 }
137
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)138 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
139 {
140 if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
141 value = (*item.intsValue_)[0];
142 return true;
143 }
144 return false;
145 }
146
147 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
148 public:
149 BundleStatusCallback() = default;
150 virtual ~BundleStatusCallback() = default;
151
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)152 void OnBundleStateChanged(const uint8_t installType,
153 const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
154
OnBundleAdded(const std::string & bundleName,const int userId)155 void OnBundleAdded(const std::string& bundleName, const int userId) override
156 {
157 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
158 }
159
OnBundleUpdated(const std::string & bundleName,const int userId)160 void OnBundleUpdated(const std::string& bundleName, const int userId) override
161 {
162 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
163 }
164
OnBundleRemoved(const std::string & bundleName,const int userId)165 void OnBundleRemoved(const std::string& bundleName, const int userId) override
166 {
167 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
168 }
169 };
170 } // namespace
171
CreateInstance()172 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
173 {
174 sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
175 sessionManager->Init();
176 return sessionManager;
177 }
178
GetInstance()179 SceneSessionManager& SceneSessionManager::GetInstance()
180 {
181 static sptr<SceneSessionManager> instance = CreateInstance();
182 return *instance;
183 }
184
SceneSessionManager()185 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
186 {
187 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
188 currentUserId_ = DEFAULT_USERID;
189 launcherService_ = new AppExecFwk::LauncherService();
190 if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
191 WLOGFE("Failed to register bundle status callback.");
192 }
193 ScbDumpSubscriber::Subscribe(g_scbSubscriber);
194 }
195
~SceneSessionManager()196 SceneSessionManager::~SceneSessionManager()
197 {
198 ScbDumpSubscriber::UnSubscribe(g_scbSubscriber);
199 }
200
Init()201 void SceneSessionManager::Init()
202 {
203 auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
204 bool isScbCoreEnabled = (deviceType == UI_TYPE_PHONE || deviceType == "tablet") &&
205 system::GetParameter("persist.window.scbcore.enable", "1") == "1";
206 Session::SetScbCoreEnabled(isScbCoreEnabled);
207
208 constexpr uint64_t interval = 5 * 1000; // 5 second
209 if (HiviewDFX::Watchdog::GetInstance().AddThread(
210 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
211 WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
212 }
213
214 bundleMgr_ = GetBundleManager();
215 LoadWindowSceneXml();
216 sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
217 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
218 InitPrepareTerminateConfig();
219 // create handler for inner command at server
220 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
221 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
222 if (eventHandler_ == nullptr) {
223 WLOGFE("Invalid eventHander");
224 return ;
225 }
226 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
227 if (ret != 0) {
228 WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
229 }
230
231 listenerController_ = std::make_shared<SessionListenerController>();
232 listenerController_->Init();
233 scbSessionHandler_ = new ScbSessionHandler();
234 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
235 StartWindowInfoReportLoop();
236 WLOGI("SSM init success.");
237 RegisterAppListener();
238 openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
239 isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1") == "1";
240 SceneInputManager::GetInstance().Init();
241
242 // MMI window state error check
243 int32_t retCode = MMI::InputManager::GetInstance()->
244 RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
245 this->NotifyWindowStateErrorFromMMI(pid, persistentId);
246 });
247 TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
248 UpdateDarkColorModeToRS();
249 }
250
InitScheduleUtils()251 void SceneSessionManager::InitScheduleUtils()
252 {
253 #ifdef RES_SCHED_ENABLE
254 SCBThreadInfo threadInfo = {
255 .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
256 .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
257 };
258 std::unordered_map<std::string, std::string> payload {
259 { "pid", threadInfo.scbPid_ },
260 { "tid", threadInfo.scbTid_ },
261 { "uid", threadInfo.scbUid_ },
262 { "bundleName", threadInfo.scbBundleName_ },
263 };
264 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
265 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
266 auto task = [threadInfo = std::move(threadInfo)]() mutable {
267 threadInfo.ssmThreadName_ = "OS_SceneSession";
268 threadInfo.ssmTid_ = std::to_string(gettid());
269 const int32_t userInteraction = 2;
270 std::unordered_map<std::string, std::string> payload{
271 { "pid", threadInfo.scbPid_ },
272 { "tid", threadInfo.ssmTid_ },
273 { "uid", threadInfo.scbUid_ },
274 { "extType", "10002" },
275 { "cgroupPrio", "1" },
276 { "isSa", "0" },
277 { "threadName", threadInfo.ssmThreadName_ }
278 };
279 uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
280 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
281 TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
282 sptr<ISystemAbilityManager> systemAbilityManager =
283 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
284 if (!systemAbilityManager) {
285 TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
286 return;
287 }
288 auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
289 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
290 if (ret != ERR_OK) {
291 TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
292 }
293 };
294 taskScheduler_->PostAsyncTask(task, "changeQosTask");
295 #endif
296 }
297
RegisterAppListener()298 void SceneSessionManager::RegisterAppListener()
299 {
300 appAnrListener_ = new (std::nothrow) AppAnrListener();
301 auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
302 if (appMgrClient_ == nullptr) {
303 WLOGFE("appMgrClient_ is nullptr.");
304 } else if (appAnrListener_ == nullptr) {
305 WLOGFE("appAnrListener_ is nullptr.");
306 } else {
307 auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
308 if (flag != ERR_OK) {
309 WLOGFE("Register app debug listener failed.");
310 } else {
311 WLOGFI("Register app debug listener success.");
312 }
313 }
314 }
315
LoadWindowSceneXml()316 void SceneSessionManager::LoadWindowSceneXml()
317 {
318 if (WindowSceneConfig::LoadConfigXml()) {
319 if (WindowSceneConfig::GetConfig().IsMap()) {
320 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
321 }
322 ConfigWindowSceneXml();
323 } else {
324 WLOGFE("Load window scene xml failed");
325 }
326 ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
327 appWindowSceneConfig_.keyboardAnimationOut_);
328 }
329
InitPrepareTerminateConfig()330 void SceneSessionManager::InitPrepareTerminateConfig()
331 {
332 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
333 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
334 PREPARE_TERMINATE_ENABLE_SIZE);
335 WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
336 if (retSysParam > 0 && !std::strcmp(value, "true")) {
337 isPrepareTerminateEnable_ = true;
338 }
339 }
340
ConfigWindowSceneXml()341 void SceneSessionManager::ConfigWindowSceneXml()
342 {
343 const auto& config = WindowSceneConfig::GetConfig();
344 WindowSceneConfig::ConfigItem item = config["windowEffect"];
345 if (item.IsMap()) {
346 ConfigWindowEffect(item);
347 }
348
349 item = config["decor"];
350 if (item.IsMap()) {
351 ConfigDecor(item);
352 }
353
354 item = config["backgroundswitch"];
355 if (item.IsInts()) {
356 auto numbers = *item.intsValue_;
357 if (numbers.size() == 1 && numbers[0] == 1) {
358 systemConfig_.backgroundswitch = true;
359 }
360 }
361 WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
362
363 item = config["defaultWindowMode"];
364 if (item.IsInts()) {
365 auto numbers = *item.intsValue_;
366 if (numbers.size() == 1 &&
367 (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
368 numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
369 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
370 }
371 }
372
373 item = config["defaultMaximizeMode"];
374 if (item.IsInts()) {
375 auto numbers = *item.intsValue_;
376 if (numbers.size() == 1 &&
377 (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
378 numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
379 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
380 }
381 }
382
383 item = config["keyboardAnimation"];
384 if (item.IsMap()) {
385 ConfigKeyboardAnimation(item);
386 }
387
388 item = config["maxFloatingWindowSize"];
389 if (item.IsInts()) {
390 auto numbers = *item.intsValue_;
391 if (numbers.size() == 1) {
392 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
393 }
394 }
395
396 item = config["windowAnimation"];
397 if (item.IsMap()) {
398 ConfigWindowAnimation(item);
399 }
400
401 item = config["startWindowTransitionAnimation"];
402 if (item.IsMap()) {
403 ConfigStartingWindowAnimation(item);
404 }
405 ConfigFreeMultiWindow();
406 ConfigWindowSizeLimits();
407 ConfigSnapshotScale();
408 ConfigWindowSceneXml(config);
409 }
410
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)411 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
412 {
413 WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
414 if (item.IsMap()) {
415 ConfigSystemUIStatusBar(item);
416 }
417 item = config["uiType"];
418 if (item.IsString()) {
419 systemConfig_.uiType_ = item.stringValue_;
420 appWindowSceneConfig_.uiType_ = item.stringValue_;
421 }
422 item = config["backgroundScreenLock"].GetProp("enable");
423 if (item.IsBool()) {
424 appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
425 }
426 item = config["rotationMode"];
427 if (item.IsString()) {
428 appWindowSceneConfig_.rotationMode_ = item.stringValue_;
429 }
430 item = config["immersive"];
431 if (item.IsMap()) {
432 ConfigWindowImmersive(item);
433 }
434 item = config["supportTypeFloatWindow"].GetProp("enable");
435 if (item.IsBool()) {
436 systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
437 }
438 }
439
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)440 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
441 {
442 AppWindowSceneConfig config;
443 WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
444 if (item.IsMap()) {
445 if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
446 appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
447 config.windowImmersive_.desktopStatusBarConfig_;
448 }
449 }
450 item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
451 if (item.IsMap()) {
452 if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
453 appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
454 config.windowImmersive_.upDownStatusBarConfig_;
455 }
456 }
457 item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
458 if (item.IsMap()) {
459 if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
460 appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
461 config.windowImmersive_.leftRightStatusBarConfig_;
462 }
463 }
464 }
465
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)466 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
467 StatusBarConfig& statusBarConfig)
468 {
469 WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
470 if (item.IsBool()) {
471 statusBarConfig.showHide_ = item.boolValue_;
472 }
473 item = config["contentColor"];
474 if (item.IsString()) {
475 statusBarConfig.contentColor_ = item.stringValue_;
476 }
477 item = config["backgroundColor"];
478 if (item.IsString()) {
479 statusBarConfig.backgroundColor_ = item.stringValue_;
480 }
481 return true;
482 }
483
ConfigFreeMultiWindow()484 void SceneSessionManager::ConfigFreeMultiWindow()
485 {
486 const auto& config = WindowSceneConfig::GetConfig();
487 WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
488 if (freeMultiWindowConfig.IsMap()) {
489 auto supportItem = freeMultiWindowConfig.GetProp("enable");
490 if (supportItem.IsBool()) {
491 systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
492 }
493 auto item = freeMultiWindowConfig["decor"];
494 if (item.IsMap()) {
495 ConfigDecor(item, false);
496 }
497 int32_t param = -1;
498 item = freeMultiWindowConfig["defaultWindowMode"];
499 if (GetSingleIntItem(item, param) &&
500 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
501 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
502 systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
503 static_cast<WindowMode>(static_cast<uint32_t>(param));
504 }
505 item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
506 if (GetSingleIntItem(item, param) && (param > 0)) {
507 systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
508 }
509 }
510 }
511
LoadFreeMultiWindowConfig(bool enable)512 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
513 {
514 FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
515 if (enable) {
516 systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
517 systemConfig_.decorModeSupportInfo_ = freeMultiWindowConfig.decorModeSupportInfo_;
518 systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
519 } else {
520 const auto& config = WindowSceneConfig::GetConfig();
521 auto item = config["decor"];
522 if (item.IsMap()) {
523 ConfigDecor(item, true);
524 }
525 int32_t param = -1;
526 item = config["defaultWindowMode"];
527 if (GetSingleIntItem(item, param) &&
528 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
529 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
530 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
531 }
532 }
533 systemConfig_.freeMultiWindowEnable_ = enable;
534 }
535
GetSystemSessionConfig() const536 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
537 {
538 return systemConfig_;
539 }
540
SwitchFreeMultiWindow(bool enable)541 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
542 {
543 if (!systemConfig_.freeMultiWindowSupport_) {
544 TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
545 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
546 }
547 LoadFreeMultiWindowConfig(enable);
548 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
549 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
550 auto sceneSession = item->second;
551 if (sceneSession == nullptr) {
552 continue;
553 }
554 auto property = sceneSession->GetSessionProperty();
555 if (property == nullptr) {
556 continue;
557 }
558 bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
559 property->GetExtensionFlag();
560 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
561 sceneSession->SwitchFreeMultiWindow(enable);
562 }
563 }
564 WindowStyleType type = enable ?
565 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
566 SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
567 return WSError::WS_OK;
568 }
569
GetFreeMultiWindowEnableState(bool & enable)570 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
571 {
572 enable = systemConfig_.freeMultiWindowEnable_;
573 return WSError::WS_OK;
574 }
575
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)576 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
577 const ContinueState& continueState)
578 {
579 TLOGI(WmsLogTag::DEFAULT, "Enter");
580 auto task = [this, token, continueState]() {
581 sptr <SceneSession> sceneSession = FindSessionByToken(token);
582 if (sceneSession == nullptr) {
583 TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
584 return WSError::WS_ERROR_INVALID_PARAM;
585 }
586 sceneSession->SetSessionInfoContinueState(continueState);
587 DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
588 static_cast<AAFwk::ContinueState>(continueState));
589 TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
590 sceneSession->GetPersistentId(), continueState);
591 return WSError::WS_OK;
592 };
593 return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
594 }
595
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)596 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
597 {
598 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
599 if (item.IsBool()) {
600 if (mainConfig) {
601 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
602 } else {
603 systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
604 }
605 bool decorEnable = item.boolValue_;
606 uint32_t support = 0;
607 std::vector<std::string> supportedModes;
608 item = decorConfig["supportedMode"];
609 if (item.IsStrings()) {
610 supportedModes = *item.stringsValue_;
611 }
612 for (auto mode : supportedModes) {
613 if (mode == "fullscreen") {
614 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
615 } else if (mode == "floating") {
616 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
617 } else if (mode == "pip") {
618 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
619 } else if (mode == "split") {
620 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
621 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
622 } else {
623 WLOGFW("Invalid supporedMode");
624 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
625 break;
626 }
627 }
628 if (mainConfig && item.IsStrings()) {
629 systemConfig_.decorModeSupportInfo_ = support;
630 }
631 if (!mainConfig && item.IsStrings()) {
632 systemConfig_.freeMultiWindowConfig_.decorModeSupportInfo_ = support;
633 }
634 }
635 }
636
AddAlphaToColor(float alpha,std::string & color)637 static void AddAlphaToColor(float alpha, std::string& color)
638 {
639 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
640 return;
641 }
642
643 uint32_t alphaValue = 0xFF * alpha;
644 std::stringstream ss;
645 ss << std::hex << alphaValue;
646 std::string strAlpha = ss.str();
647 if (strAlpha.size() == 1) {
648 strAlpha.append(1, '0');
649 }
650
651 color.insert(1, strAlpha);
652 }
653
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)654 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
655 {
656 return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
657 (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
658 AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
659 }
660
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)661 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
662 {
663 AppWindowSceneConfig config;
664 // config corner radius
665 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
666 if (item.IsMap()) {
667 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
668 appWindowSceneConfig_ = config;
669 }
670 }
671
672 // config shadow
673 item = effectConfig["appWindows"]["shadow"]["focused"];
674 if (item.IsMap()) {
675 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
676 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
677 }
678 }
679
680 item = effectConfig["appWindows"]["shadow"]["unfocused"];
681 if (item.IsMap()) {
682 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
683 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
684 }
685 }
686
687 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
688 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
689
690 WLOGFI("Config window effect successfully");
691 }
692
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)693 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
694 {
695 std::map<std::string, float> stringToCornerRadius = {
696 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
697 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
698 };
699
700 if (item.IsString()) {
701 auto value = item.stringValue_;
702 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
703 out = stringToCornerRadius[value];
704 return true;
705 }
706 }
707 return false;
708 }
709
SetEnableInputEvent(bool enabled)710 void SceneSessionManager::SetEnableInputEvent(bool enabled)
711 {
712 TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
713 enableInputEvent_ = enabled;
714 }
715
IsInputEventEnabled()716 bool SceneSessionManager::IsInputEventEnabled()
717 {
718 return enableInputEvent_;
719 }
720
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)721 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
722 {
723 for (const auto& persistentId : alivePersistentIds_) {
724 auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
725 if (it != recoveredPersistentIds.end()) {
726 continue;
727 }
728 auto sceneSession = GetSceneSession(persistentId);
729 if (sceneSession == nullptr) {
730 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
731 continue;
732 }
733 if (sceneSession->IsRecovered()) {
734 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
735 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
736 EraseSceneSessionAndMarkDirtyLocked(persistentId);
737 }
738 }
739 }
740
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)741 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
742 {
743 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
744 recoveredPersistentIds.size(), currentUserId_);
745
746 auto task = [this, recoveredPersistentIds]() {
747 ClearUnrecoveredSessions(recoveredPersistentIds);
748 std::list<AAFwk::SessionInfo> abilitySessionInfos;
749 for (const auto& persistentId : recoveredPersistentIds) {
750 if (failRecoveredPersistentIdSet_.count(persistentId)) {
751 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
752 continue;
753 }
754 auto sceneSession = GetSceneSession(persistentId);
755 if (sceneSession == nullptr) {
756 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
757 continue;
758 }
759 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
760 if (!abilitySessionInfo) {
761 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
762 continue;
763 }
764 TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
765 abilitySessionInfos.emplace_back(*abilitySessionInfo);
766 }
767 std::vector<int32_t> unrecoverableSessionIds;
768 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
769 abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
770 TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
771 unrecoverableSessionIds.size());
772 for (const auto& sessionId : unrecoverableSessionIds) {
773 auto sceneSession = GetSceneSession(sessionId);
774 if (sceneSession == nullptr) {
775 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
776 sessionId);
777 continue;
778 }
779 const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
780 if (!scnSessionInfo) {
781 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
782 continue;
783 }
784 TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
785 sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
786 }
787 removeFailRecoveredSession();
788 };
789 return taskScheduler_->PostAsyncTask(task);
790 }
791
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)792 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
793 WindowShadowConfig& outShadow)
794 {
795 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
796 if (item.IsString()) {
797 auto color = item.stringValue_;
798 uint32_t colorValue;
799 if (!ColorParser::Parse(color, colorValue)) {
800 return false;
801 }
802 outShadow.color_ = color;
803 }
804
805 item = shadowConfig["offsetX"];
806 if (item.IsFloats()) {
807 auto offsetX = *item.floatsValue_;
808 if (offsetX.size() != 1) {
809 return false;
810 }
811 outShadow.offsetX_ = offsetX[0];
812 }
813
814 item = shadowConfig["offsetY"];
815 if (item.IsFloats()) {
816 auto offsetY = *item.floatsValue_;
817 if (offsetY.size() != 1) {
818 return false;
819 }
820 outShadow.offsetY_ = offsetY[0];
821 }
822
823 item = shadowConfig["alpha"];
824 if (item.IsFloats()) {
825 auto alpha = *item.floatsValue_;
826 if (alpha.size() != 1 ||
827 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
828 return false;
829 }
830 outShadow.alpha_ = alpha[0];
831 }
832
833 item = shadowConfig["radius"];
834 if (item.IsFloats()) {
835 auto radius = *item.floatsValue_;
836 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
837 return false;
838 }
839 outShadow.radius_ = radius[0];
840 }
841
842 return true;
843 }
844
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)845 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
846 KeyboardSceneAnimationConfig& config)
847 {
848 if (item.IsMap() && item.mapValue_->count("curve")) {
849 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
850 config.curveType_ = curveType;
851 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
852 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
853 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
854 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
855 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
856 }
857 }
858
859 const WindowSceneConfig::ConfigItem& duration = item["duration"];
860 if (duration.IsInts()) {
861 auto numbers = *duration.intsValue_;
862 if (numbers.size() == 1) {
863 config.duration_ = static_cast<uint32_t>(numbers[0]);
864 }
865 }
866 }
867
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)868 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
869 {
870 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
871 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
872
873 // config system animation
874 const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
875 systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
876 {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
877 appConfigIn.duration_);
878 const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
879 systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
880 {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
881 appConfigOut.duration_);
882 }
883
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)884 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
885 KeyboardSceneAnimationConfig& animationOut)
886 {
887 if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
888 TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
889 "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
890 systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
891 systemConfig_.animationOut_.duration_);
892 return;
893 }
894
895 // default animation curve params
896 constexpr char CURVETYPE[] = "interpolatingSpring";
897 constexpr float IN_CTRLX1 = 0.0f;
898 constexpr float OUT_CTRLX1 = 4.0f;
899 constexpr float CTRLY1 = 1.0f;
900 constexpr float CTRLX2 = 342.0f;
901 constexpr float CTRLY2 = 37.0f;
902 constexpr uint32_t DURATION = 150;
903 std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
904 std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
905
906 // update system config for client
907 systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
908 systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
909
910 // update app config for server
911 animationIn.curveType_ = CURVETYPE;
912 animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
913 animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
914 animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
915 animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
916 animationIn.duration_ = DURATION;
917
918 animationOut.curveType_ = CURVETYPE;
919 animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
920 animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
921 animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
922 animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
923 animationOut.duration_ = DURATION;
924 TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
925 }
926
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)927 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
928 {
929 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
930 if (item.IsMap() && item.mapValue_->count("curve")) {
931 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
932 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
933 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
934 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
935 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
936 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
937 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
938 }
939 }
940 item = windowAnimationConfig["timing"]["duration"];
941 if (item.IsInts() && item.intsValue_->size() == 1) {
942 auto duration = *item.intsValue_;
943 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
944 }
945 item = windowAnimationConfig["scale"];
946 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
947 auto scales = *item.floatsValue_;
948 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
949 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
950 }
951 item = windowAnimationConfig["rotation"];
952 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
953 auto rotations = *item.floatsValue_;
954 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
955 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
956 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
957 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
958 }
959 item = windowAnimationConfig["translate"];
960 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
961 auto translates = *item.floatsValue_;
962 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
963 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
964 }
965 item = windowAnimationConfig["opacity"];
966 if (item.IsFloats() && item.floatsValue_->size() == 1) {
967 auto opacity = *item.floatsValue_;
968 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
969 }
970 }
971
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)972 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
973 {
974 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
975 auto item = configItem.GetProp("enable");
976 if (item.IsBool()) {
977 config.enabled_ = item.boolValue_;
978 }
979 item = configItem["timing"];
980 if (item.IsMap() && item.mapValue_->count("curve")) {
981 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
982 }
983 item = configItem["timing"]["duration"];
984 if (item.IsInts() && item.intsValue_->size() == 1) {
985 config.duration_ = (*item.intsValue_)[0];
986 }
987 item = configItem["opacityStart"];
988 if (item.IsFloats() && item.floatsValue_->size() == 1) {
989 config.opacityStart_ = (*item.floatsValue_)[0];
990 }
991 item = configItem["opacityEnd"];
992 if (item.IsFloats() && item.floatsValue_->size() == 1) {
993 config.opacityEnd_ = (*item.floatsValue_)[0];
994 }
995 }
996
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)997 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
998 const WindowSceneConfig::ConfigItem& curveConfig)
999 {
1000 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1001 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1002 static std::unordered_set<std::string> paramCurveSet = {
1003 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1004
1005 std::string curveName = "easeOut";
1006 const auto& nameItem = curveConfig.GetProp("name");
1007 if (!nameItem.IsString()) {
1008 return {curveName, {}};
1009 }
1010
1011 std::string name = nameItem.stringValue_;
1012 std::vector<float> curveParams;
1013
1014 if (paramCurveSet.find(name) != paramCurveSet.end()) {
1015 curveName = name;
1016 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1017 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1018 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1019 curveParams.begin());
1020 }
1021 } else {
1022 auto iter = curveSet.find(name);
1023 if (iter != curveSet.end()) {
1024 curveName = name;
1025 }
1026 }
1027
1028 return {curveName, curveParams};
1029 }
1030
ConfigWindowSizeLimits()1031 void SceneSessionManager::ConfigWindowSizeLimits()
1032 {
1033 const auto& config = WindowSceneConfig::GetConfig();
1034 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1035 if (item.IsMap()) {
1036 ConfigMainWindowSizeLimits(item);
1037 }
1038
1039 item = config["subWindowSizeLimits"];
1040 if (item.IsMap()) {
1041 ConfigSubWindowSizeLimits(item);
1042 }
1043 }
1044
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1045 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1046 {
1047 auto item = mainWindowSizeConifg["miniWidth"];
1048 if (item.IsInts()) {
1049 auto numbers = *item.intsValue_;
1050 if (numbers.size() == 1) {
1051 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1052 }
1053 }
1054
1055 item = mainWindowSizeConifg["miniHeight"];
1056 if (item.IsInts()) {
1057 auto numbers = *item.intsValue_;
1058 if (numbers.size() == 1) {
1059 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1060 }
1061 }
1062 }
1063
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1064 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1065 {
1066 auto item = subWindowSizeConifg["miniWidth"];
1067 if (item.IsInts()) {
1068 auto numbers = *item.intsValue_;
1069 if (numbers.size() == 1) {
1070 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1071 }
1072 }
1073
1074 item = subWindowSizeConifg["miniHeight"];
1075 if (item.IsInts()) {
1076 auto numbers = *item.intsValue_;
1077 if (numbers.size() == 1) {
1078 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1079 }
1080 }
1081 }
1082
ConfigSnapshotScale()1083 void SceneSessionManager::ConfigSnapshotScale()
1084 {
1085 const auto& config = WindowSceneConfig::GetConfig();
1086 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1087 if (item.IsFloats()) {
1088 auto snapshotScale = *item.floatsValue_;
1089 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1090 return;
1091 }
1092 snapshotScale_ = snapshotScale[0];
1093 }
1094 }
1095
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1096 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1097 {
1098 TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1099 WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1100 if (item.IsInts() && item.intsValue_->size() == 1) {
1101 bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1102 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1103 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1104 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1105 }
1106
1107 item = statusBarConfig["immersiveStatusBarBgColor"];
1108 if (item.IsString()) {
1109 auto color = item.stringValue_;
1110 uint32_t colorValue;
1111 if (!ColorParser::Parse(color, colorValue)) {
1112 return;
1113 }
1114 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1115 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1116 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1117 }
1118
1119 item = statusBarConfig["immersiveStatusBarContentColor"];
1120 if (item.IsString()) {
1121 auto color = item.stringValue_;
1122 uint32_t colorValue;
1123 if (!ColorParser::Parse(color, colorValue)) {
1124 return;
1125 }
1126 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1127 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1128 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1129 }
1130 }
1131
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1132 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1133 {
1134 rootSceneContextWeak_ = contextWeak;
1135 }
1136
GetRootSceneSession()1137 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1138 {
1139 auto task = [this]() -> sptr<RootSceneSession> {
1140 if (rootSceneSession_ != nullptr) {
1141 return rootSceneSession_;
1142 }
1143 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1144 rootSceneSession_ = new RootSceneSession();
1145 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1146 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1147 return rootSceneSession_;
1148 };
1149
1150 return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1151 }
1152
GetRootSessionAvoidSessionRect(AvoidAreaType type)1153 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1154 {
1155 sptr<RootSceneSession> rootSession = GetRootSceneSession();
1156 if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1157 return {};
1158 }
1159 DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1160 std::vector<sptr<SceneSession>> sessionVector;
1161 switch (type) {
1162 case AvoidAreaType::TYPE_SYSTEM: {
1163 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1164 break;
1165 }
1166 case AvoidAreaType::TYPE_KEYBOARD: {
1167 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1168 break;
1169 }
1170 default: {
1171 TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1172 return {};
1173 }
1174 }
1175
1176 for (auto& session : sessionVector) {
1177 if (!session->IsVisible()) {
1178 continue;
1179 }
1180 const WSRect rect = session->GetSessionRect();
1181 TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1182 return rect;
1183 }
1184 return {};
1185 }
1186
GetSceneSession(int32_t persistentId)1187 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1188 {
1189 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1190 auto iter = sceneSessionMap_.find(persistentId);
1191 if (iter == sceneSessionMap_.end()) {
1192 WLOGFD("Error found scene session with id: %{public}d", persistentId);
1193 return nullptr;
1194 }
1195 return iter->second;
1196 }
1197
GetSceneSessionByName(const ComparedSessionInfo & info)1198 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const ComparedSessionInfo& info)
1199 {
1200 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1201 for (const auto &item : sceneSessionMap_) {
1202 auto sceneSession = item.second;
1203 if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1204 sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1205 sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1206 continue;
1207 }
1208 if (info.isAtomicService_) {
1209 if ((sceneSession->GetSessionInfo().moduleName_.empty() ||
1210 sceneSession->GetSessionInfo().moduleName_ == info.moduleName_) &&
1211 (sceneSession->GetSessionInfo().abilityName_.empty() ||
1212 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_)) {
1213 return sceneSession;
1214 }
1215 } else if (sceneSession->GetSessionInfo().moduleName_ == info.moduleName_ &&
1216 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_) {
1217 return sceneSession;
1218 }
1219 }
1220 return nullptr;
1221 }
1222
GetSceneSessionByType(WindowType type)1223 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1224 {
1225 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1226 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1227 if (sceneSession && sceneSession->GetWindowType() == type) {
1228 return sceneSession;
1229 }
1230 }
1231 return nullptr;
1232 }
1233
GetSceneSessionVectorByType(WindowType type,uint64_t displayId)1234 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(
1235 WindowType type, uint64_t displayId)
1236 {
1237 if (displayId == DISPLAY_ID_INVALID) {
1238 TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1239 return {};
1240 }
1241 std::vector<sptr<SceneSession>> sceneSessionVector;
1242 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1243 for (const auto &item : sceneSessionMap_) {
1244 auto sceneSession = item.second;
1245 if (sceneSession->GetWindowType() == type &&
1246 sceneSession->GetSessionProperty() &&
1247 sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1248 sceneSessionVector.emplace_back(sceneSession);
1249 }
1250 }
1251
1252 return sceneSessionVector;
1253 }
1254
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1255 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1256 sptr<WindowSessionProperty> property)
1257 {
1258 if (property == nullptr) {
1259 TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1260 return WSError::WS_ERROR_NULLPTR;
1261 }
1262 if (sceneSession == nullptr) {
1263 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1264 return WSError::WS_ERROR_NULLPTR;
1265 }
1266 auto parentPersistentId = property->GetParentPersistentId();
1267 sceneSession->SetParentPersistentId(parentPersistentId);
1268 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1269 auto parentSession = GetSceneSession(parentPersistentId);
1270 if (parentSession == nullptr) {
1271 TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1272 return WSError::WS_ERROR_NULLPTR;
1273 }
1274 parentSession->BindDialogSessionTarget(sceneSession);
1275 parentSession->BindDialogToParentSession(sceneSession);
1276 sceneSession->SetParentSession(parentSession);
1277 TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1278 sceneSession->GetPersistentId(), parentPersistentId);
1279 }
1280 return WSError::WS_OK;
1281 }
1282
CreateSpecificSessionCallback()1283 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1284 {
1285 sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
1286 if (specificCb == nullptr) {
1287 WLOGFE("SpecificSessionCallback is nullptr");
1288 return nullptr;
1289 }
1290 specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1291 return this->RequestSceneSession(sessionInfo, property);
1292 };
1293 specificCb->onDestroy_ = [this](const int32_t persistentId) {
1294 return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1295 };
1296 specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1297 this->ClearDisplayStatusBarTemporarilyFlags();
1298 };
1299 specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1300 this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1301 };
1302 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type, uint64_t displayId) {
1303 return this->GetSceneSessionVectorByType(type, displayId);
1304 };
1305 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1306 this->UpdateAvoidArea(persistentId);
1307 };
1308 specificCb->onUpdateAvoidAreaByType_ = [this](int32_t persistentId, AvoidAreaType type) {
1309 this->UpdateAvoidAreaByType(persistentId, type);
1310 };
1311 specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1312 this->UpdateOccupiedAreaIfNeed(persistentId);
1313 };
1314 specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1315 this->NotifyWindowInfoChange(persistentId, type);
1316 };
1317 specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1318 this->NotifyMMIWindowPidChange(windowId, startMoving);
1319 };
1320 specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1321 this->NotifySessionTouchOutside(persistentId);
1322 };
1323 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1324 return this->GetAINavigationBarArea(displayId);
1325 };
1326 specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1327 this->OnOutsideDownEvent(x, y);
1328 };
1329 specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1330 return this->HandleSecureSessionShouldHide(sceneSession);
1331 };
1332 specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1333 this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1334 };
1335 specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1336 this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1337 };
1338 specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1339 this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1340 };
1341 specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1342 this->UpdateGestureBackEnabled(persistentId);
1343 };
1344 return specificCb;
1345 }
1346
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1347 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1348 {
1349 TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1350 auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1351 if (isSkip) {
1352 if (it == skipSurfaceNodeIds_.end()) {
1353 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1354 } else {
1355 return;
1356 }
1357 } else {
1358 if (it != skipSurfaceNodeIds_.end()) {
1359 skipSurfaceNodeIds_.erase(it);
1360 } else {
1361 return;
1362 }
1363 }
1364 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1365 }
1366
CreateKeyboardSessionCallback()1367 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1368 {
1369 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1370 new (std::nothrow)KeyboardSession::KeyboardSessionCallback();
1371 if (keyboardCb == nullptr) {
1372 TLOGE(WmsLogTag::WMS_KEYBOARD, "KeyboardSessionCallback is nullptr");
1373 return keyboardCb;
1374 }
1375 keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1376 return this->GetSceneSession(persistentId);
1377 };
1378 keyboardCb->onGetFocusedSessionId_ = [this] {
1379 return this->GetFocusedSessionId();
1380 };
1381 keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1382
1383 return keyboardCb;
1384 }
1385
CheckWindowId(int32_t windowId,int32_t & pid)1386 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1387 {
1388 if (!SessionPermission::IsSystemCalling()) {
1389 TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1390 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1391 }
1392
1393 auto task = [this, windowId, &pid]() -> WMError {
1394 pid = INVALID_PID;
1395 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1396 auto iter = sceneSessionMap_.find(windowId);
1397 if (iter == sceneSessionMap_.end()) {
1398 WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
1399 return WMError::WM_ERROR_INVALID_WINDOW;
1400 }
1401 auto sceneSession = iter->second;
1402 if (sceneSession == nullptr) {
1403 WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1404 return WMError::WM_ERROR_INVALID_WINDOW;
1405 }
1406 pid = sceneSession->GetCallingPid();
1407 WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1408 return WMError::WM_OK;
1409 };
1410 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1411 }
1412
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1413 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1414 {
1415 if (!isKeyboardPanelEnabled_) {
1416 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1417 return;
1418 }
1419 if (keyboardSession == nullptr) {
1420 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1421 return;
1422 }
1423 auto sessionProperty = keyboardSession->GetSessionProperty();
1424 if (sessionProperty == nullptr) {
1425 TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1426 return;
1427 }
1428 DisplayId displayId = sessionProperty->GetDisplayId();
1429 const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1430 sptr<SceneSession> panelSession;
1431 if (panelVec.size() > 1) {
1432 TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1433 return;
1434 } else if (panelVec.size() == 1) {
1435 panelSession = panelVec.front();
1436 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1437 } else {
1438 SessionInfo panelInfo = {
1439 .bundleName_ = "SCBKeyboardPanel",
1440 .moduleName_ = "SCBKeyboardPanel",
1441 .abilityName_ = "SCBKeyboardPanel",
1442 .isSystem_ = true,
1443 .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1444 .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1445 .screenId_ = static_cast<uint64_t>(displayId),
1446 .isRotable_ = true,
1447 };
1448 static bool is2in1 = systemConfig_.uiType_ == UI_TYPE_PC;
1449 if (is2in1) {
1450 panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1451 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1452 } else {
1453 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1454 }
1455 panelSession = RequestSceneSession(panelInfo, nullptr);
1456 if (panelSession == nullptr) {
1457 TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1458 return;
1459 }
1460 }
1461 keyboardSession->BindKeyboardPanelSession(panelSession);
1462 panelSession->BindKeyboardSession(keyboardSession);
1463 TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1464 panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1465 }
1466
OnSCBSystemSessionBufferAvailable(WindowType type)1467 void SceneSessionManager::OnSCBSystemSessionBufferAvailable(WindowType type)
1468 {
1469 TLOGI(WmsLogTag::WMS_MULTI_USER, "In");
1470 if (type == WindowType::WINDOW_TYPE_KEYGUARD) {
1471 TLOGI(WmsLogTag::WMS_MULTI_USER, "On screen lock buffer available");
1472 }
1473 }
1474
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1475 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1476 sptr<WindowSessionProperty> property)
1477 {
1478 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1479 sptr<SceneSession> sceneSession = nullptr;
1480 if (sessionInfo.isSystem_) {
1481 sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
1482 WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1483 if (sceneSession != nullptr &&
1484 static_cast<OHOS::Rosen::WindowType>(sessionInfo.windowType_) == WindowType::WINDOW_TYPE_KEYGUARD) {
1485 TLOGI(WmsLogTag::WMS_MULTI_USER, "Register screen lock buffer available");
1486 sceneSession->RegisterBufferAvailableCallback([this] {
1487 this->OnSCBSystemSessionBufferAvailable(WindowType::WINDOW_TYPE_KEYGUARD);
1488 });
1489 }
1490 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1491 sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
1492 if (sceneSession != nullptr) {
1493 TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1494 }
1495 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1496 sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
1497 TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1498 } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1499 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1500 sceneSession = new (std::nothrow) KeyboardSession(sessionInfo, specificCb, keyboardCb);
1501 CreateKeyboardPanelSession(sceneSession);
1502 TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1503 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1504 sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
1505 TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1506 } else {
1507 TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1508 }
1509 if (sceneSession != nullptr) {
1510 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1511 sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1512 sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1513 return this->GetAppForceLandscapeConfig(bundleName);
1514 });
1515 sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1516 this->UpdatePrivateStateAndNotify(persistentId);
1517 });
1518 sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1519 this->NotifyVisibleChange(persistentId);
1520 });
1521 sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
1522 return this->IsLastFrameLayoutFinished(isLayoutFinished);
1523 });
1524 }
1525 return sceneSession;
1526 }
1527
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1528 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1529 sptr<WindowSessionProperty> property)
1530 {
1531 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1532 auto session = GetSceneSession(sessionInfo.persistentId_);
1533 if (session != nullptr) {
1534 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1535 TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1536 return session;
1537 }
1538 if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1539 TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1540 "abilityName: %{public}s, appIndex: %{public}d",
1541 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1542 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1543 ComparedSessionInfo compareSessionInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_,
1544 sessionInfo.appIndex_, sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1545 auto sceneSession = GetSceneSessionByName(compareSessionInfo);
1546 bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1547 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1548 if (isSingleStart) {
1549 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1550 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1551 sessionInfo.persistentId_);
1552 return sceneSession;
1553 }
1554 }
1555 }
1556
1557 const char* const where = __func__;
1558 auto task = [this, sessionInfo, property, where] {
1559 TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession, appName: [%{public}s %{public}s %{public}s]"
1560 "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1561 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1562 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1563 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1564 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1565 if (sceneSession == nullptr) {
1566 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1567 return sceneSession;
1568 }
1569 InitSceneSession(sceneSession, sessionInfo, property);
1570 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1571 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1572 where, sceneSession->GetSessionInfo().ancoSceneState);
1573 bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1574 const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1575 if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1576 TLOGNI(WmsLogTag::WMS_LIFE,
1577 "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1578 where, reusedSceneSession->GetPersistentId(),
1579 reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1580 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1581 return reusedSceneSession;
1582 }
1583 if (isPreHandleSuccess) {
1584 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1585 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1586 }
1587 }
1588 {
1589 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1590 sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1591 }
1592 PerformRegisterInRequestSceneSession(sceneSession);
1593 TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession id: %{public}d, type: %{public}d",
1594 sceneSession->GetPersistentId(), sceneSession->GetWindowType());
1595 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1596 return sceneSession;
1597 };
1598 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1599 }
1600
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)1601 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1602 const sptr<WindowSessionProperty>& property)
1603 {
1604 auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1605 DisplayId curDisplayId = DISPLAY_ID_INVALID;
1606 if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1607 curDisplayId = sessionInfo.screenId_;
1608 } else if (callerSession) {
1609 auto callerSessionProperty = callerSession->GetSessionProperty();
1610 if (callerSessionProperty) {
1611 curDisplayId = callerSessionProperty->GetDisplayId();
1612 }
1613 }
1614 auto sessionProperty = sceneSession->GetSessionProperty();
1615 if (sessionProperty) {
1616 sessionProperty->SetDisplayId(curDisplayId);
1617 sceneSession->SetScreenId(curDisplayId);
1618 TLOGD(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
1619 curDisplayId);
1620 }
1621 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
1622 sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
1623 if (sessionInfo.isSystem_) {
1624 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1625 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1626 auto rootContext = rootSceneContextWeak_.lock();
1627 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1628 } else {
1629 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
1630 "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
1631 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1632 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1633 }
1634 RegisterSessionExceptionFunc(sceneSession);
1635 // Skip FillSessionInfo when atomicService free-install start.
1636 if (!IsAtomicServiceFreeInstall(sessionInfo)) {
1637 FillSessionInfo(sceneSession);
1638 }
1639 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
1640 if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
1641 sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
1642 }
1643 sceneSession->SetSystemConfig(systemConfig_);
1644 sceneSession->SetSnapshotScale(snapshotScale_);
1645 UpdateParentSessionForDialog(sceneSession, property);
1646 }
1647
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)1648 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1649 {
1650 sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
1651 if (info == nullptr) {
1652 WLOGFE("new info failed");
1653 return;
1654 }
1655 info->action_ = action;
1656 info->abilityName_ = sessionInfo.abilityName_;
1657 info->bundleName_ = sessionInfo.bundleName_;
1658 info->toScreenId_ = sessionInfo.screenId_;
1659 info->fromScreenId_ = fromScreenId;
1660 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1661 WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
1662 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1663 }
1664
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)1665 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1666 {
1667 RegisterSessionSnapshotFunc(sceneSession);
1668 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1669 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1670 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1671 RegisterGetStateFromManagerFunc(sceneSession);
1672 RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
1673 RegisterAcquireRotateAnimationConfigFunc(sceneSession);
1674 }
1675
UpdateSceneSessionWant(const SessionInfo & sessionInfo)1676 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1677 {
1678 if (sessionInfo.persistentId_ != 0) {
1679 auto session = GetSceneSession(sessionInfo.persistentId_);
1680 if (session != nullptr && sessionInfo.want != nullptr) {
1681 TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
1682 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1683 session->SetSessionInfoWant(sessionInfo.want);
1684 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
1685 } else {
1686 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1687 }
1688 } else {
1689 TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
1690 session == nullptr, sessionInfo.persistentId_);
1691 }
1692 } else {
1693 TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
1694 }
1695 }
1696
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)1697 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
1698 {
1699 if (session != nullptr) {
1700 if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1701 FillSessionInfo(session);
1702 if (CheckCollaboratorType(session->GetCollaboratorType())) {
1703 PreHandleCollaborator(session, persistentId);
1704 }
1705 }
1706 }
1707 }
1708
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)1709 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
1710 {
1711 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
1712 if (abilitySessionInfo == nullptr) {
1713 WLOGFE("abilitySessionInfo is nullptr");
1714 return nullptr;
1715 }
1716 auto sessionInfo = scnSession->GetSessionInfo();
1717 sptr<ISession> iSession(scnSession);
1718 abilitySessionInfo->sessionToken = iSession->AsObject();
1719 abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
1720 std::chrono::system_clock::now()).time_since_epoch().count());
1721 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
1722 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
1723 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
1724 abilitySessionInfo->persistentId = scnSession->GetPersistentId();
1725 abilitySessionInfo->requestCode = sessionInfo.requestCode;
1726 abilitySessionInfo->resultCode = sessionInfo.resultCode;
1727 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
1728 abilitySessionInfo->startSetting = sessionInfo.startSetting;
1729 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
1730 abilitySessionInfo->userId = currentUserId_;
1731 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
1732 abilitySessionInfo->processOptions = sessionInfo.processOptions;
1733 if (sessionInfo.want != nullptr) {
1734 abilitySessionInfo->want = *sessionInfo.want;
1735 } else {
1736 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
1737 sessionInfo.moduleName_);
1738 }
1739 int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
1740 bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
1741 if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
1742 TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
1743 appIndex, sessionInfo.appIndex_);
1744 }
1745 if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
1746 TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
1747 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
1748 }
1749 auto sessionProperty = scnSession->GetSessionProperty();
1750 if (sessionProperty) {
1751 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
1752 static_cast<int>(sessionProperty->GetDisplayId()));
1753 }
1754 if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
1755 sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
1756 abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
1757 } else {
1758 TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
1759 }
1760 return abilitySessionInfo;
1761 }
1762
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)1763 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
1764 {
1765 auto task = [this, persistentId, &isPrepareTerminate]() {
1766 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
1767 isPrepareTerminate = false;
1768 WLOGE("not support prepareTerminate, Id:%{public}d", persistentId);
1769 return WSError::WS_OK;
1770 }
1771 auto scnSession = GetSceneSession(persistentId);
1772 if (scnSession == nullptr) {
1773 WLOGFE("PrepareTerminate scnSession is nullptr, Id:%{public}d", persistentId);
1774 isPrepareTerminate = false;
1775 return WSError::WS_ERROR_NULLPTR;
1776 }
1777 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1778 if (scnSessionInfo == nullptr) {
1779 WLOGFE("PrepareTerminate scnSessionInfo is nullptr, Id:%{public}d", persistentId);
1780 isPrepareTerminate = false;
1781 return WSError::WS_ERROR_NULLPTR;
1782 }
1783 TLOGI(WmsLogTag::WMS_MAIN, "PrepareTerminateAbilityBySCB Id:%{public}d", persistentId);
1784 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
1785 PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
1786 TLOGI(WmsLogTag::WMS_MAIN, "PrepareTerminateAbilityBySCB isPrepareTerminate:%{public}d errorCode:%{public}d",
1787 isPrepareTerminate, errorCode);
1788 return WSError::WS_OK;
1789 };
1790
1791 taskScheduler_->PostSyncTask(task, "PrepareTerminate:PID:" + std::to_string(persistentId));
1792 return WSError::WS_OK;
1793 }
1794
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)1795 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
1796 {
1797 wptr<SceneSession> weakSceneSession(sceneSession);
1798 auto task = [this, weakSceneSession, isNewActive]() {
1799 sptr<SceneSession> scnSession = weakSceneSession.promote();
1800 if (scnSession == nullptr) {
1801 TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
1802 return WSError::WS_ERROR_NULLPTR;
1803 }
1804 auto persistentId = scnSession->GetPersistentId();
1805 if (!Session::IsScbCoreEnabled()) {
1806 scnSession->SetForegroundInteractiveStatus(true);
1807 }
1808 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
1809 TLOGI(WmsLogTag::WMS_MAIN, "Request active id:%{public}d system:%{public}u isNewActive:%{public}d",
1810 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_), isNewActive);
1811 if (!GetSceneSession(persistentId)) {
1812 TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
1813 return WSError::WS_ERROR_INVALID_SESSION;
1814 }
1815 auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
1816 if (ret == WSError::WS_OK) {
1817 scnSession->SetExitSplitOnBackground(false);
1818 }
1819 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
1820 return ret;
1821 };
1822 std::string taskName = "RequestSceneSessionActivation:PID:" +
1823 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
1824 taskScheduler_->PostAsyncTask(task, taskName);
1825 return WSError::WS_OK;
1826 }
1827
IsKeyboardForeground()1828 bool SceneSessionManager::IsKeyboardForeground()
1829 {
1830 bool isKeyboardForeground = false;
1831 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1832 for (const auto &item : sceneSessionMap_) {
1833 auto sceneSession = item.second;
1834 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1835 isKeyboardForeground = sceneSession->IsSessionForeground();
1836 break;
1837 }
1838 }
1839
1840 return isKeyboardForeground;
1841 }
1842
RequestInputMethodCloseKeyboard(const int32_t persistentId)1843 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
1844 {
1845 auto sceneSession = GetSceneSession(persistentId);
1846 if (sceneSession == nullptr) {
1847 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
1848 return;
1849 }
1850 // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
1851 if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
1852 !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
1853 TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
1854 persistentId, sceneSession->GetSessionState());
1855 sceneSession->RequestHideKeyboard(true);
1856 }
1857 }
1858
StartUIAbilityBySCB(sptr<SceneSession> & scnSession)1859 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
1860 {
1861 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1862 if (abilitySessionInfo == nullptr) {
1863 return ERR_NULL_OBJECT;
1864 }
1865 return StartUIAbilityBySCB(abilitySessionInfo);
1866 }
1867
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)1868 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
1869 {
1870 bool isColdStart = false;
1871 return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
1872 }
1873
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession> & scnSession,bool visibility)1874 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
1875 {
1876 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1877 if (abilitySessionInfo == nullptr) {
1878 return ERR_NULL_OBJECT;
1879 }
1880 return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
1881 }
1882
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive)1883 WSError SceneSessionManager::RequestSceneSessionActivationInner(
1884 sptr<SceneSession>& scnSession, bool isNewActive)
1885 {
1886 auto persistentId = scnSession->GetPersistentId();
1887 RequestInputMethodCloseKeyboard(persistentId);
1888 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1889 scnSession->SetIsStarting(true);
1890 scnSession->SetStartingBeforeVisible(true);
1891 }
1892 if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
1893 if (Session::IsScbCoreEnabled()) {
1894 if (scnSession->IsVisibleForeground()) {
1895 RequestSessionFocusImmediately(persistentId);
1896 } else {
1897 PostProcessFocusState state = { true, true, FocusChangeReason::SCB_START_APP };
1898 scnSession->SetPostProcessFocusState(state);
1899 }
1900 } else {
1901 RequestSessionFocusImmediately(persistentId);
1902 }
1903 }
1904 if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1905 FillSessionInfo(scnSession);
1906 if (!PreHandleCollaborator(scnSession, persistentId)) {
1907 TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
1908 persistentId, scnSession->GetSessionInfo().ancoSceneState);
1909 scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
1910 return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
1911 }
1912 }
1913 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1914 if (!scnSessionInfo) {
1915 TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
1916 return WSError::WS_ERROR_NULLPTR;
1917 }
1918 scnSession->NotifyActivation();
1919 scnSessionInfo->isNewWant = isNewActive;
1920 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1921 scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
1922 scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
1923 }
1924 TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
1925 "module: %{public}s, uri: %{public}s, appIndex: %{public}d.", persistentId,
1926 scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
1927 scnSessionInfo->want.GetElement().GetBundleName().c_str(),
1928 scnSessionInfo->want.GetElement().GetModuleName().c_str(),
1929 scnSessionInfo->want.GetElement().GetURI().c_str(),
1930 scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0));
1931 int32_t errCode = ERR_OK;
1932 bool isColdStart = false;
1933 if (systemConfig_.backgroundswitch == false) {
1934 TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
1935 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1936 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1937 } else {
1938 TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
1939 isNewActive, scnSession->GetSessionState());
1940 if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
1941 scnSession->GetSessionState() == SessionState::STATE_END) {
1942 TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
1943 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1944 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1945 } else {
1946 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
1947 scnSession->NotifySessionForeground(1, true);
1948 }
1949 }
1950 auto sessionInfo = scnSession->GetSessionInfo();
1951 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1952 WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
1953 }
1954 NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
1955
1956 if (errCode != ERR_OK) {
1957 TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
1958 scnSession->NotifySessionExceptionInner(scnSessionInfo, true, false, true);
1959 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
1960 startUIAbilityErrorFunc_(
1961 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
1962 }
1963 }
1964 if (isColdStart) {
1965 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
1966 scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
1967 scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
1968 scnSession->ResetSessionConnectState();
1969 }
1970 return WSError::WS_OK;
1971 }
1972
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)1973 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
1974 sptr<AAFwk::SessionInfo>& scnSessionInfo)
1975 {
1976 if (scnSession == nullptr || scnSessionInfo == nullptr) {
1977 return;
1978 }
1979 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1980 NotifyLoadAbility(scnSession->GetCollaboratorType(),
1981 scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
1982 NotifyUpdateSessionInfo(scnSession);
1983 NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
1984 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
1985 }
1986 }
1987
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)1988 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
1989 const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
1990 {
1991 wptr<SceneSession> weakSceneSession(sceneSession);
1992 auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
1993 auto scnSession = weakSceneSession.promote();
1994 if (scnSession == nullptr) {
1995 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
1996 return WSError::WS_ERROR_NULLPTR;
1997 }
1998 auto persistentId = scnSession->GetPersistentId();
1999 TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2000 "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2001 persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2002 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2003 scnSession->SetActive(false);
2004
2005 if (isToDesktop) {
2006 auto info = scnSession->GetSessionInfo();
2007 info.callerToken_ = nullptr;
2008 info.callingTokenId_ = 0;
2009 scnSession->SetSessionInfo(info);
2010 }
2011
2012 scnSession->BackgroundTask(isSaveSnapshot);
2013 if (!GetSceneSession(persistentId)) {
2014 TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2015 return WSError::WS_ERROR_INVALID_SESSION;
2016 }
2017 if (persistentId == brightnessSessionId_) {
2018 UpdateBrightness(focusedSessionId_);
2019 }
2020 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2021 if (!scnSessionInfo) {
2022 TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2023 return WSError::WS_ERROR_NULLPTR;
2024 }
2025 bool isPcAppInpad = false;
2026 auto property = scnSession->GetSessionProperty();
2027 if (property) {
2028 isPcAppInpad = property->GetIsPcAppInPad();
2029 }
2030 if (systemConfig_.backgroundswitch || isPcAppInpad) {
2031 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2032 scnSession->NotifySessionBackground(1, true, true);
2033 } else {
2034 TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2035 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2036 if (!isDelegator) {
2037 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2038 } else {
2039 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2040 }
2041 }
2042
2043 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2044 auto sessionInfo = scnSession->GetSessionInfo();
2045 WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2046 }
2047 return WSError::WS_OK;
2048 };
2049 std::string taskName = "RequestSceneSessionBackground:PID:" +
2050 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2051 taskScheduler_->PostAsyncTask(task, taskName);
2052 return WSError::WS_OK;
2053 }
2054
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2055 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2056 {
2057 wptr<SceneSession> weakSceneSession(sceneSession);
2058 auto task = [this, weakSceneSession, interactive]() {
2059 auto scnSession = weakSceneSession.promote();
2060 if (scnSession == nullptr) {
2061 WLOGFE("session is nullptr");
2062 return;
2063 }
2064 auto persistentId = scnSession->GetPersistentId();
2065 WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2066 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2067 if (!GetSceneSession(persistentId)) {
2068 WLOGFE("session is invalid with %{public}d", persistentId);
2069 return;
2070 }
2071 scnSession->NotifyForegroundInteractiveStatus(interactive);
2072 };
2073
2074 taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2075 }
2076
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)2077 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2078 {
2079 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2080 if (scnSession == nullptr) {
2081 TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2082 return WSError::WS_ERROR_NULLPTR;
2083 }
2084 if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2085 TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2086 auto dialogVec = scnSession->GetDialogVector();
2087 for (auto dialog : dialogVec) {
2088 if (dialog == nullptr) {
2089 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2090 continue;
2091 }
2092 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2093 if (sceneSession == nullptr) {
2094 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2095 return WSError::WS_ERROR_INVALID_SESSION;
2096 }
2097 WindowDestroyNotifyVisibility(sceneSession);
2098 dialog->NotifyDestroy();
2099 dialog->Disconnect();
2100
2101 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2102 if (dialogSceneSession != nullptr) {
2103 dialogSceneSession->ClearSpecificSessionCbMap();
2104 }
2105 {
2106 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2107 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2108 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2109 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2110 }
2111 }
2112 scnSession->ClearDialogVector();
2113 return WSError::WS_OK;
2114 }
2115 return WSError::WS_ERROR_INVALID_SESSION;
2116 }
2117
DestroySubSession(const sptr<SceneSession> & sceneSession)2118 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2119 {
2120 if (sceneSession == nullptr) {
2121 WLOGFW("sceneSession is nullptr");
2122 return;
2123 }
2124 for (const auto& elem : sceneSession->GetSubSession()) {
2125 if (elem != nullptr) {
2126 const auto& persistentId = elem->GetPersistentId();
2127 TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2128 DestroyAndDisconnectSpecificSessionInner(persistentId);
2129 }
2130 }
2131 }
2132
DestroyToastSession(const sptr<SceneSession> & sceneSession)2133 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2134 {
2135 if (sceneSession == nullptr) {
2136 TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2137 return;
2138 }
2139 for (const auto& elem : sceneSession->GetToastSession()) {
2140 if (elem != nullptr) {
2141 const auto& persistentId = elem->GetPersistentId();
2142 TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2143 DestroyAndDisconnectSpecificSessionInner(persistentId);
2144 }
2145 }
2146 }
2147
EraseSceneSessionMapById(int32_t persistentId)2148 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2149 {
2150 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2151 EraseSceneSessionAndMarkDirtyLocked(persistentId);
2152 systemTopSceneSessionMap_.erase(persistentId);
2153 nonSystemFloatSceneSessionMap_.erase(persistentId);
2154 }
2155
2156 /**
2157 * if visible session is erased, mark dirty
2158 * lock-free
2159 */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2160 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2161 {
2162 // get scene session lock-free
2163 auto iter = sceneSessionMap_.find(persistentId);
2164 if (iter == sceneSessionMap_.end()) {
2165 TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2166 return;
2167 }
2168 sptr<SceneSession> sceneSession = iter->second;
2169 if (sceneSession != nullptr && sceneSession->IsVisible()) {
2170 sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2171 }
2172 sceneSessionMap_.erase(persistentId);
2173 }
2174
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean)2175 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2176 bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2177 {
2178 auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2179 needRemoveSession, isSaveSnapshot, isForceClean]() {
2180 auto scnSession = weakSceneSession.promote();
2181 if (scnSession == nullptr) {
2182 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2183 return WSError::WS_ERROR_NULLPTR;
2184 }
2185 auto persistentId = scnSession->GetPersistentId();
2186 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2187 RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2188 lastUpdatedAvoidArea_.erase(persistentId);
2189 DestroyDialogWithMainWindow(scnSession);
2190 DestroyToastSession(scnSession);
2191 DestroySubSession(scnSession); // destroy sub session by destruction
2192 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2193 " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2194 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2195 WindowDestroyNotifyVisibility(scnSession);
2196 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2197 scnSession->DisconnectTask(false, isSaveSnapshot);
2198 if (!GetSceneSession(persistentId)) {
2199 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2200 return WSError::WS_ERROR_INVALID_SESSION;
2201 }
2202 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2203 if (!scnSessionInfo) {
2204 return WSError::WS_ERROR_NULLPTR;
2205 }
2206 scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2207 if (scnSessionInfo->resultCode == -1) {
2208 OHOS::AAFwk::Want want;
2209 scnSessionInfo->want = want;
2210 }
2211 return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2212 };
2213 std::string taskName = "RequestSceneSessionDestruction:PID:" +
2214 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2215 taskScheduler_->PostAsyncTask(task, taskName);
2216 return WSError::WS_OK;
2217 }
2218
ResetWant(sptr<SceneSession> & sceneSession)2219 void SceneSessionManager::ResetWant(sptr<SceneSession>& sceneSession)
2220 {
2221 auto& sessionInfo = sceneSession->GetSessionInfo();
2222 if (sessionInfo.want != nullptr) {
2223 const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2224 const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2225 const auto& keySessionId = sessionInfo.want->GetStringParam(KEY_SESSION_ID);
2226 auto want = std::make_shared<AAFwk::Want>();
2227 if (want != nullptr) {
2228 AppExecFwk::ElementName element;
2229 element.SetBundleName(bundleName);
2230 element.SetAbilityName(abilityName);
2231 want->SetElement(element);
2232 want->SetBundle(bundleName);
2233 if (!keySessionId.empty()) {
2234 want->SetParam(KEY_SESSION_ID, keySessionId);
2235 }
2236 sceneSession->SetSessionInfoWant(want);
2237 }
2238 }
2239 }
2240
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession,const bool isForceClean)2241 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& scnSession,
2242 sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2243 {
2244 auto persistentId = scnSession->GetPersistentId();
2245 TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}u",
2246 persistentId,
2247 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2248 if (isForceClean) {
2249 AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2250 } else {
2251 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2252 }
2253 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2254 if (needRemoveSession) {
2255 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2256 NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2257 }
2258 EraseSceneSessionMapById(persistentId);
2259 } else {
2260 // if terminate, reset want. so start from recent, start a new one.
2261 TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2262 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2263 scnSession->SetSessionInfoWant(nullptr);
2264 }
2265 ResetWant(scnSession);
2266 scnSession->ResetSessionInfoResultCode();
2267 }
2268 if (listenerController_ != nullptr) {
2269 NotifySessionForCallback(scnSession, needRemoveSession);
2270 }
2271 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2272 return WSError::WS_OK;
2273 }
2274
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)2275 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2276 const sptr<SceneSession>& sceneSession)
2277 {
2278 if (sceneSession == nullptr || sessionStage == nullptr) {
2279 TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2280 return;
2281 }
2282
2283 auto remoteObject = sessionStage->AsObject();
2284 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2285 if (windowDeath_ == nullptr) {
2286 TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2287 return;
2288 }
2289 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2290 TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2291 return;
2292 }
2293 WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2294 }
2295
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)2296 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2297 {
2298 auto task = [this, remoteObject]() {
2299 auto iter = remoteObjectMap_.find(remoteObject);
2300 if (iter == remoteObjectMap_.end()) {
2301 WLOGFE("Invalid remoteObject");
2302 return;
2303 }
2304 WLOGFD("Remote died, id: %{public}d", iter->second);
2305 auto session = GetSceneSession(iter->second);
2306 if (session == nullptr) {
2307 WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2308 return;
2309 }
2310 DestroyAndDisconnectSpecificSessionInner(iter->second);
2311 };
2312 taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2313 }
2314
CreateAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,int32_t & persistentId,sptr<ISession> & session,SystemSessionConfig & systemConfig,sptr<IRemoteObject> token)2315 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2316 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2317 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2318 SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2319 {
2320 if (property == nullptr) {
2321 WLOGFE("property is nullptr");
2322 return WSError::WS_ERROR_NULLPTR;
2323 }
2324
2325 if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2326 WLOGFE("create system window or modal subwindow permission denied!");
2327 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2328 }
2329
2330 bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2331 property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2332 bool isSystemCalling = SessionPermission::IsSystemCalling();
2333 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2334 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2335 if (parentSession) {
2336 shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2337 }
2338 }
2339 if (shouldBlock) {
2340 TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2341 return WSError::WS_ERROR_INVALID_OPERATION;
2342 }
2343
2344 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2345 property->GetExtensionFlag() == true && SessionPermission::IsStartedByUIExtension()) {
2346 auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2347 if (extensionParentSession == nullptr) {
2348 WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2349 return WSError::WS_ERROR_NULLPTR;
2350 }
2351 SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2352 AAFwk::UIExtensionHostInfo hostInfo;
2353 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2354 if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2355 WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2356 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2357 hostInfo.elementName_.GetBundleName().c_str());
2358 return WSError::WS_ERROR_INVALID_WINDOW;
2359 }
2360 }
2361
2362 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2363 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2364 WLOGFE("The alarm window has been deprecated!");
2365 return WSError::WS_ERROR_INVALID_WINDOW;
2366 }
2367
2368 if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2369 WLOGFE("pip window is not enable to create.");
2370 return WSError::WS_DO_NOTHING;
2371 }
2372 TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2373 property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2374
2375 // Get pid and uid before posting task.
2376 auto pid = IPCSkeleton::GetCallingRealPid();
2377 auto uid = IPCSkeleton::GetCallingUid();
2378 auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2379 &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2380 if (property == nullptr) {
2381 WLOGFE("[WMSSub][WMSSystem] property is nullptr");
2382 return WSError::WS_ERROR_NULLPTR;
2383 }
2384 const auto& type = property->GetWindowType();
2385 // create specific session
2386 SessionInfo info;
2387 info.windowType_ = static_cast<uint32_t>(type);
2388 info.bundleName_ = property->GetSessionInfo().bundleName_;
2389 info.abilityName_ = property->GetSessionInfo().abilityName_;
2390 info.moduleName_ = property->GetSessionInfo().moduleName_;
2391
2392 ClosePipWindowIfExist(type);
2393 sptr<SceneSession> newSession = RequestSceneSession(info, property);
2394 if (newSession == nullptr) {
2395 TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2396 return WSError::WS_ERROR_NULLPTR;
2397 }
2398 auto errCode = newSession->ConnectInner(
2399 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2400 newSession->SetIsSystemSpecificSession(isSystemCalling);
2401 systemConfig = systemConfig_;
2402 if (property) {
2403 persistentId = property->GetPersistentId();
2404 }
2405
2406 NotifyCreateSpecificSession(newSession, property, type);
2407 session = newSession;
2408 AddClientDeathRecipient(sessionStage, newSession);
2409 TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2410 "parentId: %{public}d, type: %{public}d",
2411 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2412 return errCode;
2413 };
2414
2415 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2416 }
2417
ClosePipWindowIfExist(WindowType type)2418 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2419 {
2420 if (type != WindowType::WINDOW_TYPE_PIP) {
2421 return;
2422 }
2423 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2424 for (const auto& iter: sceneSessionMap_) {
2425 auto& session = iter.second;
2426 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2427 session->NotifyCloseExistPipWindow();
2428 break;
2429 }
2430 }
2431 }
2432
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)2433 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2434 {
2435 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2436 for (const auto& iter: sceneSessionMap_) {
2437 auto& session = iter.second;
2438 if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2439 pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2440 session->IsSessionForeground()) {
2441 if (startPiPFailedFunc_) {
2442 startPiPFailedFunc_();
2443 }
2444 TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2445 return false;
2446 }
2447 }
2448 return true;
2449 }
2450
isEnablePiPCreate(const sptr<WindowSessionProperty> & property)2451 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2452 {
2453 if (isScreenLocked_) {
2454 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2455 return false;
2456 }
2457 Rect pipRect = property->GetRequestRect();
2458 if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2459 TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2460 return false;
2461 }
2462 if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2463 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2464 return false;
2465 }
2466 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2467 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2468 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2469 return false;
2470 }
2471 return true;
2472 }
2473
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)2474 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2475 {
2476 WindowType type = property->GetWindowType();
2477 if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
2478 return true;
2479 }
2480
2481 if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
2482 TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
2483 return false;
2484 }
2485
2486 if (!SessionPermission::IsSystemCalling()) {
2487 TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
2488 return false;
2489 }
2490
2491 return true;
2492 }
2493
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)2494 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
2495 {
2496 WindowType type = property->GetWindowType();
2497 if (WindowHelper::IsUIExtensionWindow(type)) {
2498 // UIExtension window disallowed.
2499 return false;
2500 }
2501 if (!WindowHelper::IsSystemWindow(type)) {
2502 // type is not system
2503 return true;
2504 }
2505 if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)
2506 && SessionPermission::IsStartedByInputMethod()) {
2507 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
2508 WLOGFD("check create permission success, input method app create input method window.");
2509 return true;
2510 }
2511 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
2512 // some system types could be created by normal app
2513 return true;
2514 }
2515 if (type == WindowType::WINDOW_TYPE_FLOAT &&
2516 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2517 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
2518 if (systemConfig_.supportTypeFloatWindow_) {
2519 WLOGFD("check create float window permission success on 2in1 device.");
2520 return true;
2521 }
2522 }
2523 if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
2524 int32_t parentId = property->GetParentPersistentId();
2525 auto parentSession = GetSceneSession(parentId);
2526 if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2527 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2528 TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
2529 return true;
2530 } else {
2531 TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
2532 }
2533 }
2534 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
2535 TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
2536 return true;
2537 }
2538 WLOGFE("check system window permission failed.");
2539 return false;
2540 }
2541
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)2542 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
2543 {
2544 SessionInfo sessionInfo;
2545 if (property == nullptr) {
2546 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2547 return sessionInfo;
2548 }
2549 sessionInfo = property->GetSessionInfo();
2550 sessionInfo.persistentId_ = property->GetPersistentId();
2551 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
2552 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
2553 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
2554 sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
2555 ? SessionState::STATE_ACTIVE
2556 : SessionState::STATE_BACKGROUND;
2557 sessionInfo.isPersistentRecover_ = true;
2558 TLOGI(WmsLogTag::WMS_RECOVER,
2559 "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
2560 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
2561 "windowState=%{public}u",
2562 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2563 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_);
2564 return sessionInfo;
2565 }
2566
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)2567 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
2568 {
2569 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
2570 "%{public}d", alivePersistentIds.size(), currentUserId_);
2571 alivePersistentIds_ = alivePersistentIds;
2572 }
2573
IsNeedRecover(const int32_t persistentId)2574 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
2575 {
2576 auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
2577 if (it == alivePersistentIds_.end()) {
2578 TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
2579 return false;
2580 }
2581 return true;
2582 }
2583
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)2584 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
2585 bool isSpecificSession)
2586 {
2587 if (property == nullptr) {
2588 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2589 return WSError::WS_ERROR_NULLPTR;
2590 }
2591 if (!CheckSystemWindowPermission(property)) {
2592 TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
2593 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2594 }
2595 if (isSpecificSession) {
2596 if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
2597 return WSError::WS_ERROR_INVALID_PARAM;
2598 }
2599 } else {
2600 if (!IsNeedRecover(property->GetPersistentId())) {
2601 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2602 return WSError::WS_ERROR_INVALID_PARAM;
2603 }
2604 }
2605 return WSError::WS_OK;
2606 }
2607
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)2608 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2609 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2610 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
2611 {
2612 auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
2613 if (propCheckRet != WSError::WS_OK) {
2614 return propCheckRet;
2615 }
2616 auto pid = IPCSkeleton::GetCallingRealPid();
2617 auto uid = IPCSkeleton::GetCallingUid();
2618 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
2619 if (recoveringFinished_) {
2620 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2621 return WSError::WS_ERROR_INVALID_OPERATION;
2622 }
2623 // recover specific session
2624 SessionInfo info = RecoverSessionInfo(property);
2625 TLOGI(WmsLogTag::WMS_RECOVER, "callingWindowId = %{public}" PRIu32, property->GetCallingSessionId());
2626 ClosePipWindowIfExist(property->GetWindowType());
2627 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
2628 if (sceneSession == nullptr) {
2629 TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
2630 return WSError::WS_ERROR_NULLPTR;
2631 }
2632
2633 auto persistentId = sceneSession->GetPersistentId();
2634 if (persistentId != info.persistentId_) {
2635 TLOGE(WmsLogTag::WMS_RECOVER,
2636 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
2637 info.persistentId_, persistentId, property->GetParentPersistentId());
2638 failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
2639 EraseSceneSessionMapById(persistentId);
2640 return WSError::WS_ERROR_INVALID_SESSION;
2641 }
2642
2643 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2644 if (errCode != WSError::WS_OK) {
2645 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
2646 EraseSceneSessionMapById(persistentId);
2647 return errCode;
2648 }
2649 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
2650 CacheSubSessionForRecovering(sceneSession, property);
2651 NotifySessionUnfocusedToClient(persistentId);
2652 AddClientDeathRecipient(sessionStage, sceneSession);
2653 session = sceneSession;
2654 return errCode;
2655 };
2656 return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
2657 }
2658
NotifyRecoveringFinished()2659 void SceneSessionManager::NotifyRecoveringFinished()
2660 {
2661 taskScheduler_->PostAsyncTask([this]() {
2662 TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
2663 recoveringFinished_ = true;
2664 recoverSubSessionCacheMap_.clear();
2665 }, "NotifyRecoveringFinished");
2666 }
2667
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)2668 void SceneSessionManager::CacheSubSessionForRecovering(
2669 sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
2670 {
2671 if (recoveringFinished_) {
2672 TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
2673 return;
2674 }
2675
2676 if (sceneSession == nullptr || property == nullptr) {
2677 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
2678 return;
2679 }
2680
2681 auto windowType = property->GetWindowType();
2682 if (!SessionHelper::IsSubWindow(windowType)) {
2683 return;
2684 }
2685
2686 auto persistentId = property->GetParentPersistentId();
2687 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
2688 return;
2689 }
2690
2691 TLOGI(WmsLogTag::WMS_RECOVER,
2692 "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
2693 sceneSession->GetPersistentId(), persistentId);
2694
2695 if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
2696 recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
2697 } else {
2698 recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
2699 }
2700 }
2701
RecoverCachedSubSession(int32_t persistentId)2702 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
2703 {
2704 auto iter = recoverSubSessionCacheMap_.find(persistentId);
2705 if (iter == recoverSubSessionCacheMap_.end()) {
2706 return;
2707 }
2708
2709 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
2710 for (auto& sceneSession : iter->second) {
2711 NotifyCreateSubSession(persistentId, sceneSession);
2712 }
2713 recoverSubSessionCacheMap_.erase(iter);
2714 }
2715
NotifySessionUnfocusedToClient(int32_t persistentId)2716 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
2717 {
2718 if (listenerController_ != nullptr) {
2719 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
2720 listenerController_->NotifySessionUnfocused(persistentId);
2721 }
2722 }
2723
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)2724 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
2725 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2726 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
2727 {
2728 auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
2729 if (propCheckRet != WSError::WS_OK) {
2730 return propCheckRet;
2731 }
2732 auto pid = IPCSkeleton::GetCallingRealPid();
2733 auto uid = IPCSkeleton::GetCallingUid();
2734 auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
2735 if (recoveringFinished_) {
2736 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2737 return WSError::WS_ERROR_INVALID_OPERATION;
2738 }
2739 if (recoverSceneSessionFunc_ == nullptr) {
2740 TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
2741 return WSError::WS_ERROR_NULLPTR;
2742 }
2743 SessionInfo sessionInfo = RecoverSessionInfo(property);
2744 sptr<SceneSession> sceneSession = nullptr;
2745 if (SessionHelper::IsMainWindow(property->GetWindowType())) {
2746 sceneSession = RequestSceneSession(sessionInfo, nullptr);
2747 } else {
2748 sceneSession = RequestSceneSession(sessionInfo, property);
2749 }
2750 if (sceneSession == nullptr) {
2751 TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
2752 return WSError::WS_ERROR_NULLPTR;
2753 }
2754 int32_t persistentId = sceneSession->GetPersistentId();
2755 if (persistentId != sessionInfo.persistentId_) {
2756 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
2757 sessionInfo.persistentId_, persistentId);
2758 EraseSceneSessionMapById(persistentId);
2759 return WSError::WS_ERROR_INVALID_SESSION;
2760 }
2761 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2762 if (ret != WSError::WS_OK) {
2763 TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
2764 EraseSceneSessionMapById(sessionInfo.persistentId_);
2765 return ret;
2766 }
2767 sceneSession->SetRecovered(true);
2768 recoverSceneSessionFunc_(sceneSession, sessionInfo);
2769 NotifySessionUnfocusedToClient(persistentId);
2770 session = sceneSession;
2771 return WSError::WS_OK;
2772 };
2773 return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
2774 }
2775
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)2776 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
2777 {
2778 TLOGI(WmsLogTag::WMS_RECOVER, "called");
2779 recoverSceneSessionFunc_ = func;
2780 }
2781
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)2782 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
2783 {
2784 createSystemSessionFunc_ = func;
2785 }
2786
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)2787 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
2788 {
2789 createKeyboardSessionFunc_ = func;
2790 }
2791
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)2792 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
2793 {
2794 startPiPFailedFunc_ = std::move(func);
2795 }
2796
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)2797 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
2798 const NotifyCreateSubSessionFunc& func)
2799 {
2800 TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
2801 auto task = [this, persistentId, func]() {
2802 createSubSessionFuncMap_[persistentId] = func;
2803 RecoverCachedSubSession(persistentId);
2804 return WMError::WM_OK;
2805 };
2806 taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
2807 }
2808
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)2809 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
2810 sptr<WindowSessionProperty> property, const WindowType& type)
2811 {
2812 if (newSession == nullptr) {
2813 WLOGFE("newSession is nullptr");
2814 return;
2815 }
2816 if (property == nullptr) {
2817 WLOGFE("property is nullptr");
2818 return;
2819 }
2820 if (SessionHelper::IsSystemWindow(type)) {
2821 if (type == WindowType::WINDOW_TYPE_FLOAT) {
2822 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2823 if (parentSession != nullptr) {
2824 newSession->SetParentSession(parentSession);
2825 }
2826 }
2827 if (type == WindowType::WINDOW_TYPE_TOAST) {
2828 NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
2829 }
2830 if (type != WindowType::WINDOW_TYPE_DIALOG) {
2831 if (WindowHelper::IsSystemSubWindow(type)) {
2832 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2833 } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
2834 && createKeyboardSessionFunc_) {
2835 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
2836 } else if (createSystemSessionFunc_) {
2837 createSystemSessionFunc_(newSession);
2838 }
2839 TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
2840 newSession->GetPersistentId(), type);
2841 } else {
2842 TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, \
2843 type:%{public}d", newSession->GetPersistentId(), type);
2844 return;
2845 }
2846 } else if (SessionHelper::IsSubWindow(type)) {
2847 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2848 TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
2849 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
2850 } else {
2851 TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
2852 newSession->GetPersistentId(), type);
2853 }
2854 }
2855
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)2856 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
2857 {
2858 if (session == nullptr) {
2859 TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
2860 return;
2861 }
2862 auto iter = createSubSessionFuncMap_.find(persistentId);
2863 if (iter == createSubSessionFuncMap_.end()) {
2864 TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
2865 return;
2866 }
2867
2868 sptr<SceneSession> parentSession = nullptr;
2869 if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
2870 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2871 parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
2872 } else {
2873 parentSession = GetSceneSession(persistentId);
2874 }
2875 if (parentSession == nullptr) {
2876 TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
2877 persistentId, session->GetPersistentId());
2878 return;
2879 }
2880 parentSession->AddSubSession(session);
2881 session->SetParentSession(parentSession);
2882 if (iter->second) {
2883 iter->second(session);
2884 }
2885 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
2886 persistentId, session->GetPersistentId());
2887 }
2888
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)2889 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
2890 const std::map<int32_t, sptr<SceneSession>>& sessionMap)
2891 {
2892 if (persistentId == INVALID_SESSION_ID) {
2893 TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
2894 return nullptr;
2895 }
2896 auto iter = sessionMap.find(persistentId);
2897 if (iter == sessionMap.end()) {
2898 WLOGFD("Error found scene session with id: %{public}d", persistentId);
2899 return nullptr;
2900 }
2901 sptr<SceneSession> parentSession = iter->second;
2902 if (parentSession == nullptr) {
2903 TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
2904 return nullptr;
2905 }
2906 bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
2907 parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
2908 if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
2909 TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
2910 return parentSession;
2911 }
2912 return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
2913 }
2914
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)2915 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
2916 {
2917 if (session == nullptr) {
2918 TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
2919 return;
2920 }
2921
2922 auto parentSession = GetSceneSession(persistentId);
2923 if (parentSession == nullptr) {
2924 TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
2925 persistentId, session->GetPersistentId());
2926 return;
2927 }
2928 parentSession->AddToastSession(session);
2929 session->SetParentSession(parentSession);
2930 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
2931 persistentId, session->GetPersistentId());
2932 }
2933
UnregisterCreateSubSessionListener(int32_t persistentId)2934 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
2935 {
2936 TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
2937 auto task = [this, persistentId]() {
2938 auto iter = createSubSessionFuncMap_.find(persistentId);
2939 if (iter != createSubSessionFuncMap_.end()) {
2940 createSubSessionFuncMap_.erase(persistentId);
2941 } else {
2942 TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
2943 }
2944 return WMError::WM_OK;
2945 };
2946 taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
2947 }
2948
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)2949 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
2950 {
2951 WLOGFD("SetStatusBarEnabledChangeListener");
2952 if (!func) {
2953 WLOGFD("set func is null");
2954 }
2955 statusBarEnabledChangeFunc_ = func;
2956 }
2957
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)2958 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
2959 const ProcessGestureNavigationEnabledChangeFunc& func)
2960 {
2961 WLOGFD("SetGestureNavigationEnabledChangeListener");
2962 if (!func) {
2963 WLOGFD("set func is null");
2964 }
2965 gestureNavigationEnabledChangeFunc_ = func;
2966 }
2967
OnOutsideDownEvent(int32_t x,int32_t y)2968 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
2969 {
2970 TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
2971 if (outsideDownEventFunc_) {
2972 outsideDownEventFunc_(x, y);
2973 }
2974 }
2975
NotifySessionTouchOutside(int32_t persistentId)2976 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
2977 {
2978 auto task = [this, persistentId]() {
2979 int32_t callingSessionId = INVALID_SESSION_ID;
2980 auto sceneSession = GetSceneSession(persistentId);
2981 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2982 callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
2983 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
2984 persistentId, callingSessionId);
2985 }
2986 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2987 for (const auto &item : sceneSessionMap_) {
2988 sceneSession = item.second;
2989 if (sceneSession == nullptr) {
2990 continue;
2991 }
2992 if (!(sceneSession->IsVisible() ||
2993 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
2994 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
2995 continue;
2996 }
2997 auto sessionId = sceneSession->GetPersistentId();
2998 if ((!sceneSession->CheckOutTouchOutsideRegister()) &&
2999 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3000 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3001 continue;
3002 }
3003 if (sessionId == callingSessionId || sessionId == persistentId) {
3004 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3005 continue;
3006 }
3007 sceneSession->NotifyTouchOutside();
3008 }
3009 };
3010
3011 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3012 return;
3013 }
3014
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)3015 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3016 {
3017 WLOGFD("SetOutsideDownEventListener");
3018 outsideDownEventFunc_ = func;
3019 }
3020
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)3021 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
3022 {
3023 for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
3024 if (iter->second != persistentId) {
3025 continue;
3026 }
3027 if (windowDeath_ == nullptr) {
3028 TLOGE(WmsLogTag::WMS_LIFE, "death recipient is null");
3029 } else {
3030 if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
3031 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
3032 }
3033 }
3034 remoteObjectMap_.erase(iter);
3035 break;
3036 }
3037 }
3038
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3039 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3040 {
3041 auto sceneSession = GetSceneSession(persistentId);
3042 if (sceneSession == nullptr) {
3043 return WSError::WS_ERROR_NULLPTR;
3044 }
3045 auto ret = sceneSession->UpdateActiveStatus(false);
3046 WindowDestroyNotifyVisibility(sceneSession);
3047 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
3048 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3049 if (parentSession == nullptr) {
3050 TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3051 } else {
3052 parentSession->RemoveDialogToParentSession(sceneSession);
3053 }
3054 }
3055 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_TOAST) {
3056 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3057 if (parentSession != nullptr) {
3058 TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3059 parentSession->RemoveToastSession(persistentId);
3060 } else {
3061 TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3062 }
3063 }
3064 ret = sceneSession->Disconnect();
3065 sceneSession->ClearSpecificSessionCbMap();
3066 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3067 DestroySubSession(sceneSession);
3068 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3069 if (parentSession != nullptr) {
3070 TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3071 parentSession->RemoveSubSession(sceneSession->GetPersistentId());
3072 } else {
3073 TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3074 }
3075 }
3076 {
3077 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3078 EraseSceneSessionAndMarkDirtyLocked(persistentId);
3079 systemTopSceneSessionMap_.erase(persistentId);
3080 nonSystemFloatSceneSessionMap_.erase(persistentId);
3081 UnregisterCreateSubSessionListener(persistentId);
3082 }
3083 ClearSpecificSessionRemoteObjectMap(persistentId);
3084 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3085 return ret;
3086 }
3087
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3088 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3089 {
3090 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3091 auto task = [this, persistentId, callingPid]() {
3092 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3093 auto sceneSession = GetSceneSession(persistentId);
3094 if (sceneSession == nullptr) {
3095 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3096 return WSError::WS_ERROR_NULLPTR;
3097 }
3098
3099 if (callingPid != sceneSession->GetCallingPid()) {
3100 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3101 return WSError::WS_ERROR_INVALID_PERMISSION;
3102 }
3103 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3104 };
3105
3106 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3107 }
3108
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)3109 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3110 const sptr<IRemoteObject>& callback)
3111 {
3112 if (callback == nullptr) {
3113 return WSError::WS_ERROR_NULLPTR;
3114 }
3115 const auto callingPid = IPCSkeleton::GetCallingRealPid();
3116 auto task = [this, persistentId, callingPid, callback]() {
3117 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3118 auto sceneSession = GetSceneSession(persistentId);
3119 if (sceneSession == nullptr) {
3120 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3121 return WSError::WS_ERROR_NULLPTR;
3122 }
3123
3124 if (callingPid != sceneSession->GetCallingPid()) {
3125 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3126 return WSError::WS_ERROR_INVALID_PERMISSION;
3127 }
3128 sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3129 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3130 };
3131
3132 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3133 }
3134
GetWindowSceneConfig() const3135 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3136 {
3137 return appWindowSceneConfig_;
3138 }
3139
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)3140 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3141 {
3142 auto task = [this, config]() {
3143 TLOGI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3144 rotateAnimationConfig_.duration_ = config.duration_;
3145 };
3146 taskScheduler_->PostAsyncTask(task, "UpdateRotateAnimationConfig");
3147 }
3148
ProcessBackEvent()3149 WSError SceneSessionManager::ProcessBackEvent()
3150 {
3151 auto task = [this]() {
3152 auto session = GetSceneSession(focusedSessionId_);
3153 if (!session) {
3154 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId_);
3155 return WSError::WS_ERROR_INVALID_SESSION;
3156 }
3157 TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
3158 focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3159 if (needBlockNotifyFocusStatusUntilForeground_) {
3160 TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
3161 if (session->GetSessionInfo().abilityInfo != nullptr &&
3162 session->GetSessionInfo().abilityInfo->unclearableMission) {
3163 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3164 return WSError::WS_OK;
3165 }
3166 session->RequestSessionBack(true);
3167 return WSError::WS_OK;
3168 }
3169 if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3170 rootSceneProcessBackEventFunc_();
3171 } else {
3172 session->ProcessBackEvent();
3173 }
3174 return WSError::WS_OK;
3175 };
3176
3177 taskScheduler_->PostAsyncTask(task, __func__);
3178 return WSError::WS_OK;
3179 }
3180
InitUserInfo(int32_t userId,std::string & fileDir)3181 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3182 {
3183 if (userId == DEFAULT_USERID || fileDir.empty()) {
3184 TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3185 return WSError::WS_DO_NOTHING;
3186 }
3187 TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3188 auto task = [this, userId, &fileDir]() {
3189 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3190 TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3191 }
3192 if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3193 TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3194 }
3195 currentUserId_ = userId;
3196 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3197 RegisterSecSurfaceInfoListener();
3198 return WSError::WS_OK;
3199 };
3200 return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3201 }
3202
NotifySwitchingUser(const bool isUserActive)3203 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3204 {
3205 auto task = [this, isUserActive]() {
3206 TLOGI(WmsLogTag::WMS_MULTI_USER, "Notify switching user. IsUserActive=%{public}u, currentUserId=%{public}d",
3207 isUserActive, currentUserId_);
3208 isUserBackground_ = !isUserActive;
3209 SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3210 if (isUserActive) { // switch to current user
3211 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3212 // notify screenSessionManager to recover current user
3213 ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3214 FlushWindowInfoToMMI(true);
3215 NotifyAllAccessibilityInfo();
3216 rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3217 } else { // switch to another user
3218 SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3219 rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3220 }
3221 return WSError::WS_OK;
3222 };
3223 taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3224 }
3225
GetBundleManager()3226 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3227 {
3228 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3229 if (systemAbilityMgr == nullptr) {
3230 WLOGFE("Failed to get SystemAbilityManager.");
3231 return nullptr;
3232 }
3233
3234 auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3235 if (bmsObj == nullptr) {
3236 WLOGFE("Failed to get BundleManagerService.");
3237 return nullptr;
3238 }
3239
3240 return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3241 }
3242
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)3243 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3244 const AppExecFwk::AbilityInfo& abilityInfo)
3245 {
3246 auto context = rootSceneContextWeak_.lock();
3247 if (!context) {
3248 WLOGFE("context is nullptr.");
3249 return nullptr;
3250 }
3251 auto resourceMgr = context->GetResourceManager();
3252 if (!resourceMgr) {
3253 WLOGFE("resourceMgr is nullptr.");
3254 return nullptr;
3255 }
3256 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3257 if (!resConfig) {
3258 WLOGFE("resConfig is nullptr.");
3259 return nullptr;
3260 }
3261 resourceMgr->GetResConfig(*resConfig);
3262 resourceMgr = Global::Resource::CreateResourceManager(
3263 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3264 if (!resourceMgr) {
3265 WLOGFE("resourceMgr is nullptr.");
3266 return nullptr;
3267 }
3268 resourceMgr->UpdateResConfig(*resConfig);
3269
3270 std::string loadPath;
3271 if (!abilityInfo.hapPath.empty()) { // zipped hap
3272 loadPath = abilityInfo.hapPath;
3273 } else {
3274 loadPath = abilityInfo.resourcePath;
3275 }
3276
3277 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3278 WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3279 }
3280 return resourceMgr;
3281 }
3282
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)3283 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3284 std::string& path, uint32_t& bgColor)
3285 {
3286 auto resourceMgr = GetResourceManager(abilityInfo);
3287 if (!resourceMgr) {
3288 WLOGFE("resourceMgr is nullptr.");
3289 return false;
3290 }
3291
3292 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3293 WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3294 return false;
3295 }
3296
3297 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3298 WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3299 return false;
3300 }
3301
3302 if (!abilityInfo.hapPath.empty()) { // zipped hap
3303 auto pos = path.find_last_of('.');
3304 if (pos == std::string::npos) {
3305 WLOGFE("Format error, path %{private}s.", path.c_str());
3306 return false;
3307 }
3308 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3309 }
3310 return true;
3311 }
3312
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3313 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3314 {
3315 if (!bundleMgr_) {
3316 WLOGFE("bundleMgr_ is nullptr.");
3317 return;
3318 }
3319 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3320 if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3321 WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3322 return;
3323 }
3324 AAFwk::Want want;
3325 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3326 AppExecFwk::AbilityInfo abilityInfo;
3327 if (!bundleMgr_->QueryAbilityInfo(
3328 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3329 WLOGFE("Get ability info from BMS failed!");
3330 return;
3331 }
3332
3333 if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3334 CacheStartingWindowInfo(abilityInfo, path, bgColor);
3335 }
3336 WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3337 abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3338 }
3339
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3340 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3341 const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3342 {
3343 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3344 std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3345 auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3346 if (iter == startingWindowMap_.end()) {
3347 return false;
3348 }
3349 auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3350 const auto& infoMap = iter->second;
3351 auto infoMapIter = infoMap.find(key);
3352 if (infoMapIter == infoMap.end()) {
3353 return false;
3354 }
3355 path = infoMapIter->second.startingWindowIconPath_;
3356 bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3357 return true;
3358 }
3359
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)3360 void SceneSessionManager::CacheStartingWindowInfo(
3361 const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3362 {
3363 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3364 auto key = abilityInfo.moduleName + abilityInfo.name;
3365 StartingWindowInfo info = {
3366 .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3367 .startingWindowIconId_ = abilityInfo.startWindowIconId,
3368 .startingWindowBackgroundColor_ = bgColor,
3369 .startingWindowIconPath_ = path,
3370 };
3371 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3372 auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3373 if (iter != startingWindowMap_.end()) {
3374 auto& infoMap = iter->second;
3375 infoMap.emplace(key, info);
3376 return;
3377 }
3378 if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3379 startingWindowMap_.erase(startingWindowMap_.begin());
3380 }
3381 std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3382 startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3383 }
3384
OnBundleUpdated(const std::string & bundleName,int userId)3385 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3386 {
3387 taskScheduler_->PostAsyncTask([this, bundleName]() {
3388 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3389 auto iter = startingWindowMap_.find(bundleName);
3390 if (iter != startingWindowMap_.end()) {
3391 startingWindowMap_.erase(iter);
3392 }
3393 },
3394 "OnBundleUpdated");
3395 }
3396
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3397 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3398 {
3399 taskScheduler_->PostAsyncTask([this]() {
3400 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3401 startingWindowMap_.clear();
3402 },
3403 "OnConfigurationUpdated");
3404 }
3405
FillSessionInfo(sptr<SceneSession> & sceneSession)3406 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3407 {
3408 auto sessionInfo = sceneSession->GetSessionInfo();
3409 if (sessionInfo.bundleName_.empty()) {
3410 WLOGFE("bundleName_ is empty");
3411 return;
3412 }
3413 if (sessionInfo.isSystem_) {
3414 WLOGFD("is system scene!");
3415 return;
3416 }
3417 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3418 sessionInfo.moduleName_);
3419 if (abilityInfo == nullptr) {
3420 WLOGFE("abilityInfo is nullptr!");
3421 return;
3422 }
3423 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3424 sceneSession->SetSessionInfoTime(GetCurrentTime());
3425 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3426 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3427 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3428 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3429 }
3430 TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3431 "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3432 abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3433 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3434 }
3435
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)3436 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3437 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3438 {
3439 if (!bundleMgr_) {
3440 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3441 return nullptr;
3442 }
3443 AAFwk::Want want;
3444 want.SetElementName("", bundleName, abilityName, moduleName);
3445 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3446 if (abilityInfo == nullptr) {
3447 WLOGFE("abilityInfo is nullptr!");
3448 return nullptr;
3449 }
3450 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3451 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3452 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3453 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
3454 if (!ret) {
3455 WLOGFE("Get ability info from BMS failed!");
3456 return nullptr;
3457 }
3458 return abilityInfo;
3459 }
3460
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)3461 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
3462 uint32_t& topWinId, uint32_t& zOrder)
3463 {
3464 const auto& subVec = session->GetSubSession();
3465 for (const auto& subSession : subVec) {
3466 if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
3467 TLOGW(WmsLogTag::WMS_SUB,
3468 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
3469 continue;
3470 }
3471 if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3472 subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
3473 subSession->GetZOrder() > zOrder) {
3474 topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
3475 zOrder = subSession->GetZOrder();
3476 TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
3477 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
3478 }
3479 if (subSession->GetSubSession().size() > 0) {
3480 GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
3481 }
3482 }
3483 }
3484
3485 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)3486 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
3487 {
3488 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3489 auto task = [this, mainWinId, &topWinId, callingPid]() {
3490 const auto& mainSession = GetSceneSession(mainWinId);
3491 if (mainSession == nullptr) {
3492 return WMError::WM_ERROR_INVALID_WINDOW;
3493 }
3494
3495 if (callingPid != mainSession->GetCallingPid()) {
3496 WLOGFE("Permission denied, not destroy by the same process");
3497 return WMError::WM_ERROR_INVALID_PERMISSION;
3498 }
3499 uint32_t zOrder = mainSession->GetZOrder();
3500 topWinId = mainWinId;
3501 GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
3502 TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
3503 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
3504 return WMError::WM_OK;
3505 };
3506
3507 if (!Session::IsScbCoreEnabled()) {
3508 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3509 }
3510 bool postNow = false;
3511 auto mainSession = GetSceneSession(mainWinId);
3512 if (mainSession != nullptr) {
3513 postNow = !(mainSession->GetUIStateDirty());
3514 }
3515 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
3516 if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
3517 taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
3518 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3519 }
3520 TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
3521 {
3522 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
3523 if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
3524 std::cv_status::timeout) {
3525 TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
3526 }
3527 }
3528 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3529 }
3530
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)3531 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
3532 int32_t windowId, int32_t& mainWindowId)
3533 {
3534 auto iter = sceneSessionMap.find(windowId);
3535 if (iter == sceneSessionMap.end()) {
3536 TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
3537 return WMError::WM_ERROR_NULLPTR;
3538 }
3539 sptr<SceneSession> sceneSession = iter->second;
3540 if (sceneSession == nullptr) {
3541 TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
3542 return WMError::WM_ERROR_NULLPTR;
3543 }
3544 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3545 mainWindowId = sceneSession->GetPersistentId();
3546 return WMError::WM_OK;
3547 }
3548 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3549 WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
3550 return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
3551 }
3552 // not sub window, dialog, return invalid id
3553 mainWindowId = INVALID_SESSION_ID;
3554 return WMError::WM_OK;
3555 }
3556
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)3557 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
3558 {
3559 if (windowId == INVALID_SESSION_ID) {
3560 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3561 return WMError::WM_ERROR_INVALID_PARAM;
3562 }
3563 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3564 return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
3565 }
3566
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3567 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
3568 const sptr<SceneSession>& sceneSession)
3569 {
3570 auto systemBarProperties = property->GetSystemBarProperty();
3571 for (auto iter : systemBarProperties) {
3572 if (iter.first == type) {
3573 sceneSession->SetSystemBarProperty(iter.first, iter.second);
3574 TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
3575 static_cast<int32_t>(iter.first), iter.second.enable_);
3576 }
3577 }
3578 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3579 }
3580
3581 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3582 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
3583 const sptr<SceneSession>& sceneSession)
3584 {
3585 if (!SessionPermission::IsSystemCalling()) {
3586 TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
3587 return WMError::WM_ERROR_NOT_SYSTEM_APP;
3588 }
3589
3590 sceneSession->SetTopmost(property->IsTopmost());
3591 return WMError::WM_OK;
3592 }
3593
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3594 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3595 const sptr<SceneSession>& sceneSession)
3596 {
3597 auto propertyOld = sceneSession->GetSessionProperty();
3598 if (propertyOld == nullptr) {
3599 TLOGI(WmsLogTag::DEFAULT, "session property null");
3600 return;
3601 }
3602
3603 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
3604 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
3605 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
3606 TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
3607 return;
3608 }
3609
3610 if (IsSessionVisibleForeground(sceneSession)) {
3611 if (hideNonSystemFloatingWindowsOld) {
3612 UpdateForceHideState(sceneSession, propertyOld, false);
3613 } else {
3614 UpdateForceHideState(sceneSession, property, true);
3615 }
3616 }
3617 }
3618
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)3619 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
3620 const sptr<WindowSessionProperty>& property, bool add)
3621 {
3622 if (property == nullptr) {
3623 WLOGFD("property is nullptr");
3624 return;
3625 }
3626 auto persistentId = sceneSession->GetPersistentId();
3627 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
3628 bool notifyAll = false;
3629 if (add) {
3630 if (property->GetHideNonSystemFloatingWindows()) {
3631 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
3632 notifyAll = !forceHideFloatOld;
3633 } else if (property->IsFloatingWindowAppType()) {
3634 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
3635 if (forceHideFloatOld) {
3636 sceneSession->NotifyForceHideChange(true);
3637 }
3638 }
3639 } else {
3640 if (property->GetHideNonSystemFloatingWindows()) {
3641 systemTopSceneSessionMap_.erase(persistentId);
3642 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
3643 } else if (property->IsFloatingWindowAppType()) {
3644 nonSystemFloatSceneSessionMap_.erase(persistentId);
3645 if (property->GetForceHide()) {
3646 sceneSession->NotifyForceHideChange(false);
3647 }
3648 }
3649 }
3650 if (notifyAll) {
3651 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
3652 for (const auto &item : nonSystemFloatSceneSessionMap_) {
3653 auto forceHideSceneSession = item.second;
3654 auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
3655 if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
3656 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
3657 }
3658 }
3659 }
3660 }
3661
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)3662 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
3663 {
3664 #ifdef POWER_MANAGER_ENABLE
3665 auto task = [this, sceneSession]() {
3666 if (sceneSession == nullptr) {
3667 WLOGFE("session is invalid");
3668 return;
3669 }
3670 WLOGFD("Win: %{public}s, is turn on%{public}d",
3671 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
3672 std::string identity = IPCSkeleton::ResetCallingIdentity();
3673 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
3674 WLOGI("turn screen on");
3675 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
3676 }
3677 // set ipc identity to raw
3678 IPCSkeleton::SetCallingIdentity(identity);
3679 };
3680 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
3681
3682 #else
3683 WLOGFD("Can not found the sub system of PowerMgr");
3684 #endif
3685 }
3686
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)3687 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
3688 {
3689 #ifdef POWER_MANAGER_ENABLE
3690 wptr<SceneSession> weakSceneSession(sceneSession);
3691 auto task = [this, weakSceneSession, requireLock]() {
3692 auto scnSession = weakSceneSession.promote();
3693 if (scnSession == nullptr) {
3694 WLOGFE("session is invalid");
3695 return;
3696 }
3697 if (requireLock && scnSession->keepScreenLock_ == nullptr) {
3698 // reset ipc identity
3699 std::string identity = IPCSkeleton::ResetCallingIdentity();
3700 scnSession->keepScreenLock_ =
3701 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
3702 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
3703 // set ipc identity to raw
3704 IPCSkeleton::SetCallingIdentity(identity);
3705 }
3706 if (scnSession->keepScreenLock_ == nullptr) {
3707 return;
3708 }
3709 bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession);
3710 TLOGNI(WmsLogTag::DEFAULT, "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d]",
3711 scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
3712 scnSession->IsVisible(), requireLock, shouldLock);
3713 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
3714 ErrCode res;
3715 std::string identity = IPCSkeleton::ResetCallingIdentity();
3716 if (shouldLock) {
3717 res = scnSession->keepScreenLock_->Lock();
3718 } else {
3719 res = scnSession->keepScreenLock_->UnLock();
3720 }
3721 // set ipc identity to raw
3722 IPCSkeleton::SetCallingIdentity(identity);
3723 if (res != ERR_OK) {
3724 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
3725 requireLock, res);
3726 }
3727 };
3728 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
3729 #else
3730 WLOGFD("Can not found the sub system of PowerMgr");
3731 #endif
3732 }
3733
NotifyVisibleChange(int32_t persistentId)3734 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
3735 {
3736 auto sceneSession = GetSceneSession(persistentId);
3737 if (sceneSession == nullptr) {
3738 return false;
3739 }
3740 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
3741 ProcessWindowModeType();
3742 return true;
3743 }
3744
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)3745 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
3746 {
3747 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
3748 if (GetDisplayBrightness() != brightness && eventHandler_ != nullptr &&
3749 GetFocusedSessionId() == sceneSession->GetPersistentId()) {
3750 bool setBrightnessRet = false;
3751 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3752 auto task = []() {
3753 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3754 };
3755 setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
3756 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3757 } else {
3758 auto task = [brightness]() {
3759 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3760 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3761 };
3762 setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
3763 SetDisplayBrightness(brightness);
3764 }
3765 if (!setBrightnessRet) {
3766 WLOGFE("Report post listener callback task failed. the task name is SetBrightness");
3767 }
3768 }
3769 #else
3770 WLOGFD("Can not found the sub system of DisplayPowerMgr");
3771 #endif
3772 brightnessSessionId_ = sceneSession->GetPersistentId();
3773 return WSError::WS_OK;
3774 }
3775
UpdateBrightness(int32_t persistentId)3776 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
3777 {
3778 auto sceneSession = GetSceneSession(persistentId);
3779 if (sceneSession == nullptr) {
3780 WLOGFE("session is invalid");
3781 return WSError::WS_ERROR_NULLPTR;
3782 }
3783 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
3784 sceneSession->GetSessionInfo().isSystem_)) {
3785 WLOGW("only app main window can set brightness");
3786 return WSError::WS_DO_NOTHING;
3787 }
3788 auto brightness = sceneSession->GetBrightness();
3789 WLOGFI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
3790 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3791 if (GetDisplayBrightness() != brightness) {
3792 WLOGI("adjust brightness with default value");
3793 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3794 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3795 }
3796 brightnessSessionId_ = INVALID_WINDOW_ID;
3797 } else {
3798 if (GetDisplayBrightness() != brightness) {
3799 WLOGI("adjust brightness with value");
3800 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3801 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3802 SetDisplayBrightness(brightness);
3803 }
3804 brightnessSessionId_ = sceneSession->GetPersistentId();
3805 }
3806 return WSError::WS_OK;
3807 }
3808
GetCurrentUserId() const3809 int32_t SceneSessionManager::GetCurrentUserId() const
3810 {
3811 return currentUserId_;
3812 }
3813
SetDisplayBrightness(float brightness)3814 void SceneSessionManager::SetDisplayBrightness(float brightness)
3815 {
3816 displayBrightness_ = brightness;
3817 }
3818
GetDisplayBrightness() const3819 float SceneSessionManager::GetDisplayBrightness() const
3820 {
3821 return displayBrightness_;
3822 }
3823
SetGestureNavigaionEnabled(bool enable)3824 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
3825 {
3826 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3827 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
3828 return WMError::WM_ERROR_NOT_SYSTEM_APP;
3829 }
3830 std::string callerBundleName = SessionPermission::GetCallingBundleName();
3831 TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
3832 auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
3833 SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
3834 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
3835 WLOGFE("callback func is null");
3836 return WMError::WM_OK;
3837 }
3838 if (gestureNavigationEnabledChangeFunc_) {
3839 gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
3840 }
3841 if (statusBarEnabledChangeFunc_) {
3842 statusBarEnabledChangeFunc_(enable, bundleName);
3843 }
3844 return WMError::WM_OK;
3845 };
3846 return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
3847 }
3848
SetFocusedSessionId(int32_t persistentId)3849 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
3850 {
3851 if (focusedSessionId_ == persistentId) {
3852 WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
3853 return WSError::WS_DO_NOTHING;
3854 }
3855 lastFocusedSessionId_ = focusedSessionId_;
3856 focusedSessionId_ = persistentId;
3857 return WSError::WS_OK;
3858 }
3859
GetFocusedSessionId() const3860 int32_t SceneSessionManager::GetFocusedSessionId() const
3861 {
3862 return focusedSessionId_;
3863 }
3864
GetFocusWindowInfo(FocusChangeInfo & focusInfo)3865 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
3866 {
3867 if (!SessionPermission::IsSACalling()) {
3868 WLOGFE("GetFocusWindowInfo permission denied!");
3869 return;
3870 }
3871 auto sceneSession = GetSceneSession(focusedSessionId_);
3872 if (sceneSession) {
3873 WLOGFD("Get focus session info success");
3874 focusInfo.windowId_ = sceneSession->GetWindowId();
3875 focusInfo.displayId_ = static_cast<DisplayId>(0);
3876 focusInfo.pid_ = sceneSession->GetCallingPid();
3877 focusInfo.uid_ = sceneSession->GetCallingUid();
3878 focusInfo.windowType_ = sceneSession->GetWindowType();
3879 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
3880 }
3881 return;
3882 }
3883
IsValidDigitString(const std::string & windowIdStr)3884 static bool IsValidDigitString(const std::string& windowIdStr)
3885 {
3886 if (windowIdStr.empty()) {
3887 return false;
3888 }
3889 for (char ch : windowIdStr) {
3890 if ((ch >= '0' && ch <= '9')) {
3891 continue;
3892 }
3893 WLOGFE("invalid window id");
3894 return false;
3895 }
3896 return true;
3897 }
3898
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)3899 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
3900 {
3901 if (sceneSession == nullptr) {
3902 WLOGFE("session is nullptr");
3903 return;
3904 }
3905 NotifySessionExceptionFunc sessionExceptionFunc = [this](
3906 const SessionInfo& info, bool needRemoveSession = false, bool startFail = false) {
3907 auto task = [this, info]() {
3908 auto scnSession = GetSceneSession(info.persistentId_);
3909 if (scnSession == nullptr) {
3910 TLOGW(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, Not found session, id: %{public}d",
3911 info.persistentId_);
3912 return;
3913 }
3914 if (listenerController_ == nullptr) {
3915 TLOGW(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, listenerController_ is nullptr");
3916 return;
3917 }
3918 if (scnSession->GetSessionInfo().isSystem_) {
3919 TLOGW(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, id: %{public}d is system",
3920 scnSession->GetPersistentId());
3921 return;
3922 }
3923 TLOGI(WmsLogTag::WMS_LIFE, "NotifySessionExceptionFunc, errorCode: %{public}d, id: %{public}d",
3924 info.errorCode, info.persistentId_);
3925 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
3926 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
3927 TLOGD(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
3928 "or foreground timeout, id: %{public}d", info.persistentId_);
3929 listenerController_->NotifySessionClosed(info.persistentId_);
3930 }
3931 };
3932 taskScheduler_->PostVoidSyncTask(task, "sessionException");
3933 };
3934 sceneSession->SetSessionExceptionListener(sessionExceptionFunc, false);
3935 TLOGD(WmsLogTag::WMS_LIFE, "RegisterSessionExceptionFunc success, id: %{public}d", sceneSession->GetPersistentId());
3936 }
3937
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)3938 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
3939 {
3940 if (sceneSession == nullptr) {
3941 WLOGFE("session is nullptr");
3942 return;
3943 }
3944 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
3945 auto sceneSession = GetSceneSession(persistentId);
3946 if (sceneSession == nullptr) {
3947 WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
3948 return;
3949 }
3950 if (sceneSession->GetSessionInfo().isSystem_) {
3951 WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
3952 return;
3953 }
3954 auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
3955 if (abilityInfoPtr == nullptr) {
3956 WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
3957 return;
3958 }
3959 if (listenerController_ == nullptr) {
3960 WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
3961 return;
3962 }
3963 if (!abilityInfoPtr->excludeFromMissions) {
3964 listenerController_->NotifySessionSnapshotChanged(persistentId);
3965 }
3966 };
3967 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
3968 WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
3969 }
3970
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)3971 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
3972 {
3973 if (sceneSession == nullptr) {
3974 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
3975 return;
3976 }
3977 AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
3978 config.duration_ = rotateAnimationConfig_.duration_;
3979 };
3980 sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
3981 TLOGD(WmsLogTag::DEFAULT, "Register acquire Rotate Animation config success, id: %{public}d",
3982 sceneSession->GetPersistentId());
3983 }
3984
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)3985 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
3986 {
3987 if (scnSession == nullptr) {
3988 WLOGFW("NotifySessionForCallback, scnSession is nullptr");
3989 return;
3990 }
3991 if (scnSession->GetSessionInfo().isSystem_) {
3992 WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
3993 return;
3994 }
3995 WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
3996 static_cast<uint32_t>(needRemoveSession));
3997 if (scnSession->GetSessionInfo().appIndex_ != 0) {
3998 WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
3999 scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
4000 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4001 return;
4002 }
4003 if (needRemoveSession) {
4004 WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
4005 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4006 return;
4007 }
4008 if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
4009 WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
4010 } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4011 (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4012 WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4013 scnSession->GetPersistentId());
4014 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4015 return;
4016 }
4017 WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
4018 listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
4019 }
4020
NotifyWindowInfoChangeFromSession(int32_t persistentId)4021 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4022 {
4023 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4024 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4025 if (sceneSession == nullptr) {
4026 WLOGFE("sceneSession nullptr");
4027 return;
4028 }
4029
4030 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4031 }
4032
IsSessionVisible(const sptr<SceneSession> & session)4033 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4034 {
4035 if (session == nullptr) {
4036 return false;
4037 }
4038 if (Session::IsScbCoreEnabled()) {
4039 return session->IsVisible();
4040 }
4041 const auto& state = session->GetSessionState();
4042 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4043 const auto& parentSceneSession = session->GetParentSession();
4044 if (parentSceneSession == nullptr) {
4045 WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
4046 return false;
4047 }
4048 const auto& parentState = parentSceneSession->GetSessionState();
4049 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4050 if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
4051 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
4052 return false;
4053 }
4054 WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4055 return true;
4056 }
4057 WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4058 return false;
4059 }
4060
4061 if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
4062 WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
4063 return true;
4064 }
4065 WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
4066 return false;
4067 }
4068
IsSessionVisibleForeground(const sptr<SceneSession> & session)4069 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4070 {
4071 if (session == nullptr) {
4072 return false;
4073 }
4074 if (Session::IsScbCoreEnabled()) {
4075 return session->IsVisibleForeground();
4076 }
4077 return IsSessionVisible(session);
4078 }
4079
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)4080 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4081 {
4082 if (session == nullptr) {
4083 return;
4084 }
4085 int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4086 WSRect rect = session->GetSessionRect();
4087 std::string sName;
4088 if (session->GetSessionInfo().isSystem_) {
4089 sName = session->GetSessionInfo().abilityName_;
4090 } else {
4091 sName = session->GetWindowName();
4092 }
4093 uint32_t flag = 0;
4094 uint64_t displayId = INVALID_SCREEN_ID;
4095 auto sessionProperty = session->GetSessionProperty();
4096 if (sessionProperty) {
4097 flag = sessionProperty->GetWindowFlags();
4098 displayId = sessionProperty->GetDisplayId();
4099 }
4100 uint32_t orientation = 0;
4101 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4102 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4103 // std::setw is used to set the output width and different width values are set to keep the format aligned.
4104 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4105 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4106 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4107 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4108 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4109 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4110 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4111 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4112 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4113 << "[ "
4114 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4115 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4116 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4117 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4118 << "]"
4119 << " [ "
4120 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4121 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4122 << "]"
4123 << " [ "
4124 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4125 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4126 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4127 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4128 << "]"
4129 << std::endl;
4130 }
4131
GetAllSessionDumpInfo(std::string & dumpInfo)4132 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4133 {
4134 int32_t screenGroupId = 0;
4135 std::ostringstream oss;
4136 oss << "-------------------------------------ScreenGroup " << screenGroupId
4137 << "-------------------------------------" << std::endl;
4138 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
4139 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]"
4140 << std::endl;
4141
4142 std::vector<sptr<SceneSession>> allSession;
4143 std::vector<sptr<SceneSession>> backgroundSession;
4144 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4145 {
4146 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4147 sceneSessionMapCopy = sceneSessionMap_;
4148 }
4149 for (const auto& elem : sceneSessionMapCopy) {
4150 auto curSession = elem.second;
4151 if (curSession == nullptr || (!curSession->GetSessionInfo().isSystem_ && (curSession->GetSessionState() <
4152 SessionState::STATE_FOREGROUND || curSession->GetSessionState() > SessionState::STATE_BACKGROUND))) {
4153 WLOGFW("Session is nullptr or session state is invalid, id: %{public}d, state: %{public}u",
4154 curSession->GetPersistentId(), curSession->GetSessionState());
4155 continue;
4156 }
4157 if (IsSessionVisibleForeground(curSession)) {
4158 allSession.push_back(curSession);
4159 } else {
4160 backgroundSession.push_back(curSession);
4161 }
4162 }
4163 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4164 uint32_t count = 0;
4165 for (const auto& session : allSession) {
4166 if (session == nullptr) {
4167 continue;
4168 }
4169 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4170 oss << "---------------------------------------------------------------------------------------"
4171 << std::endl;
4172 }
4173 DumpSessionInfo(session, oss);
4174 count++;
4175 }
4176 oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4177 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4178 dumpInfo.append(oss.str());
4179 return WSError::WS_OK;
4180 }
4181
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)4182 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4183 {
4184 dumpRootSceneFunc_ = func;
4185 }
4186
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)4187 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4188 const std::vector<std::string>& params, std::string& dumpInfo)
4189 {
4190 std::vector<std::string> resetParams;
4191 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4192 if (resetParams.empty()) {
4193 WLOGI("do not dump ui info");
4194 return;
4195 }
4196
4197 if (!session->GetSessionInfo().isSystem_) {
4198 WLOGFI("Dump normal session, not system");
4199 dumpInfoFuture_.ResetLock({});
4200 session->DumpSessionElementInfo(resetParams);
4201 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4202 for (auto& info: infos) {
4203 dumpInfo.append(info).append("\n");
4204 }
4205 } else {
4206 WLOGFI("Dump system session");
4207 std::vector<std::string> infos;
4208 dumpRootSceneFunc_(resetParams, infos);
4209 for (auto& info: infos) {
4210 dumpInfo.append(info).append("\n");
4211 }
4212 }
4213 }
4214
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)4215 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4216 const std::string& strId)
4217 {
4218 uint64_t persistentId = std::stoull(strId);
4219 auto session = GetSceneSession(persistentId);
4220 if (session == nullptr) {
4221 return WSError::WS_ERROR_INVALID_PARAM;
4222 }
4223 auto sessionProperty = session->GetSessionProperty();
4224 if (sessionProperty == nullptr) {
4225 return WSError::WS_ERROR_INVALID_PARAM;
4226 }
4227
4228 WSRect rect = session->GetSessionRect();
4229 std::string isVisible = session->IsVisible() ? "true" : "false";
4230 std::string focusable = session->GetFocusable() ? "true" : "false";
4231 std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4232 bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4233 std::string isPrivacyMode = privacyMode ? "true" : "false";
4234 bool isFirstFrameAvailable = true;
4235 std::ostringstream oss;
4236 oss << "WindowName: " << session->GetWindowName() << std::endl;
4237 oss << "DisplayId: " << 0 << std::endl;
4238 oss << "WinId: " << session->GetPersistentId() << std::endl;
4239 oss << "Pid: " << session->GetCallingPid() << std::endl;
4240 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4241 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4242 oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4243 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4244 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4245 oss << "IsVisible: " << isVisible << std::endl;
4246 oss << "Focusable: " << focusable << std::endl;
4247 oss << "DecoStatus: " << decoStatus << std::endl;
4248 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
4249 oss << "WindowRect: " << "[ "
4250 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4251 << " ]" << std::endl;
4252 oss << "scaleX: " << session->GetScaleX() << std::endl;
4253 oss << "scaleY: " << session->GetScaleY() << std::endl;
4254 oss << "Offset: " << "[ "
4255 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4256 oss << "Scale: " << "[ "
4257 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4258 << session->GetPivotX() << ", " << session->GetPivotY()
4259 << " ]" << std::endl;
4260 dumpInfo.append(oss.str());
4261
4262 DumpSessionElementInfo(session, params, dumpInfo);
4263 return WSError::WS_OK;
4264 }
4265
GetSCBDebugDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params)4266 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params)
4267 {
4268 std::string cmd = ScbDumpSubscriber::JoinCommands(params, params.size());
4269
4270 // publish data
4271 bool ret = eventHandler_->PostSyncTask([this, cmd] { return g_scbSubscriber->Publish(cmd); }, "PublishSCBDumper");
4272 if (!ret) {
4273 return WSError::WS_ERROR_INVALID_OPERATION;
4274 }
4275
4276 // get response event
4277 auto task = [this, &dumpInfo]() {
4278 dumpInfo.append(g_scbSubscriber->GetDebugDumpInfo(WAIT_TIME));
4279 return WSError::WS_OK;
4280 };
4281 eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4282
4283 return WSError::WS_OK;
4284 }
4285
NotifyDumpInfoResult(const std::vector<std::string> & info)4286 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4287 {
4288 dumpInfoFuture_.SetValue(info);
4289 WLOGFD("NotifyDumpInfoResult");
4290 }
4291
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)4292 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4293 {
4294 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4295 WLOGFE("GetSessionDumpInfo permission denied!");
4296 return WSError::WS_ERROR_INVALID_PERMISSION;
4297 }
4298
4299 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4300 return GetAllSessionDumpInfo(dumpInfo);
4301 }
4302 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4303 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4304 }
4305 if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2:params num
4306 return GetSCBDebugDumpInfo(dumpInfo, params);
4307 }
4308 if (params.size() >= 2 && params[0] == ARG_DUMP_PIPLINE && IsValidDigitString(params[1])) { // 2: params num
4309 return GetTotalUITreeInfo(params[1], dumpInfo);
4310 }
4311 return WSError::WS_ERROR_INVALID_OPERATION;
4312 }
4313
GetTotalUITreeInfo(const std::string & strId,std::string & dumpInfo)4314 WSError SceneSessionManager::GetTotalUITreeInfo(const std::string& strId, std::string& dumpInfo)
4315 {
4316 TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4317 uint64_t screenId = std::stoull(strId);
4318 if (dumpUITreeFunc_) {
4319 dumpUITreeFunc_(screenId, dumpInfo);
4320 } else {
4321 TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4322 }
4323 return WSError::WS_OK;
4324 }
4325
SetDumpUITreeFunc(const DumpUITreeFunc & func)4326 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4327 {
4328 dumpUITreeFunc_ = func;
4329 }
4330
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)4331 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
4332 {
4333 onFlushUIParamsFunc_ = std::move(func);
4334 }
4335
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)4336 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
4337 {
4338 isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
4339 }
4340
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)4341 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4342 {
4343 // notify RS
4344 WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4345 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4346 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4347 sceneSession->GetSessionInfo().bundleName_.c_str(),
4348 sceneSession->GetSessionInfo().abilityName_.c_str(),
4349 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4350 uint64_t focusNodeId = 0; // 0 means invalid
4351 if (sceneSession->GetSurfaceNode() == nullptr) {
4352 WLOGFW("focused window surfaceNode is null");
4353 } else {
4354 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4355 }
4356 FocusAppInfo appInfo = {
4357 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4358 sceneSession->GetSessionInfo().bundleName_,
4359 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4360 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4361 }
4362
4363 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4364 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4365 {
4366 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4367 {
4368 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4369 for (auto& iter : sceneSessionMap_) {
4370 ret.push_back(iter);
4371 }
4372 }
4373 std::sort(ret.begin(), ret.end(), cmp);
4374 return ret;
4375 }
4376
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)4377 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4378 {
4379 if (isFromTopToBottom) {
4380 TraverseSessionTreeFromTopToBottom(func);
4381 } else {
4382 TraverseSessionTreeFromBottomToTop(func);
4383 }
4384 return;
4385 }
4386
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4387 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4388 {
4389 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4390 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4391 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4392 return lhsZOrder < rhsZOrder;
4393 };
4394 auto sceneSessionVector = GetSceneSessionVector(cmp);
4395
4396 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
4397 auto session = iter->second;
4398 if (session == nullptr) {
4399 WLOGFE("session is nullptr");
4400 continue;
4401 }
4402 if (func(session)) {
4403 return;
4404 }
4405 }
4406 return;
4407 }
4408
TraverseSessionTreeFromBottomToTop(TraverseFunc func)4409 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
4410 {
4411 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4412 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4413 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4414 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4415 return lhsZOrder < rhsZOrder;
4416 };
4417 auto sceneSessionVector = GetSceneSessionVector(cmp);
4418 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
4419 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
4420 auto session = iter->second;
4421 if (session == nullptr) {
4422 WLOGFE("session is nullptr");
4423 continue;
4424 }
4425 if (func(session)) {
4426 return;
4427 }
4428 }
4429 return;
4430 }
4431
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4432 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
4433 FocusChangeReason reason)
4434 {
4435 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4436 auto sceneSession = GetSceneSession(persistentId);
4437 if (sceneSession == nullptr) {
4438 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
4439 return WMError::WM_ERROR_NULLPTR;
4440 }
4441 int32_t callingPid = IPCSkeleton::GetCallingPid();
4442 if (callingPid != sceneSession->GetCallingPid() &&
4443 !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
4444 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
4445 return WMError::WM_ERROR_INVALID_CALLING;
4446 }
4447 auto task = [this, persistentId, isFocused, byForeground, reason]() {
4448 if (isFocused) {
4449 RequestSessionFocus(persistentId, byForeground, reason);
4450 } else {
4451 RequestSessionUnfocus(persistentId, reason);
4452 }
4453 };
4454 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
4455 focusChangeReason_ = reason;
4456 return WMError::WM_OK;
4457 }
4458
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4459 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
4460 FocusChangeReason reason)
4461 {
4462 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4463 auto task = [this, persistentId, isFocused, byForeground, reason]() {
4464 if (isFocused) {
4465 if (reason == FocusChangeReason::FOREGROUND) {
4466 RequestSessionFocusImmediately(persistentId);
4467 return;
4468 }
4469 if (reason == FocusChangeReason::MOVE_UP) {
4470 auto session = GetSceneSession(persistentId);
4471 if (session && !session->IsFocused()) {
4472 PostProcessFocusState state = { true, true, reason };
4473 session->SetPostProcessFocusState(state);
4474 }
4475 return;
4476 }
4477 // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
4478 if (reason == FocusChangeReason::CLICK) {
4479 return;
4480 }
4481 if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
4482 auto session = GetSceneSession(persistentId);
4483 if (session && !session->IsFocused()) {
4484 PostProcessFocusState state = { true, true, reason };
4485 session->SetPostProcessFocusState(state);
4486 }
4487 }
4488 } else {
4489 RequestSessionUnfocus(persistentId, reason);
4490 }
4491 };
4492 taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
4493 return WMError::WM_OK;
4494 }
4495
RequestAllAppSessionUnfocus()4496 void SceneSessionManager::RequestAllAppSessionUnfocus()
4497 {
4498 auto task = [this]() {
4499 RequestAllAppSessionUnfocusInner();
4500 };
4501 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
4502 return;
4503 }
4504
4505 /**
4506 * request focus and ignore its state
4507 * only used when app main window start before foreground
4508 */
RequestSessionFocusImmediately(int32_t persistentId)4509 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
4510 {
4511 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
4512 // base block
4513 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4514 if (basicCheckRet != WSError::WS_OK) {
4515 return basicCheckRet;
4516 }
4517 auto sceneSession = GetSceneSession(persistentId);
4518 if (sceneSession == nullptr) {
4519 WLOGFE("[WMSComm]session is nullptr");
4520 return WSError::WS_ERROR_INVALID_SESSION;
4521 }
4522 if (!sceneSession->GetFocusable()) {
4523 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
4524 return WSError::WS_DO_NOTHING;
4525 }
4526 if (!sceneSession->IsFocusedOnShow()) {
4527 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4528 return WSError::WS_DO_NOTHING;
4529 }
4530
4531 // specific block
4532 FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
4533 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
4534 if (specificCheckRet != WSError::WS_OK) {
4535 return specificCheckRet;
4536 }
4537
4538 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4539 if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
4540 needBlockNotifyFocusStatusUntilForeground_ = true;
4541 }
4542 ShiftFocus(sceneSession, reason);
4543 return WSError::WS_OK;
4544 }
4545
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)4546 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
4547 {
4548 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
4549 persistentId, byForeground, reason);
4550 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4551 if (basicCheckRet != WSError::WS_OK) {
4552 return basicCheckRet;
4553 }
4554 auto sceneSession = GetSceneSession(persistentId);
4555 if (sceneSession == nullptr) {
4556 WLOGFE("[WMSComm]session is nullptr");
4557 return WSError::WS_ERROR_INVALID_SESSION;
4558 }
4559 if (!sceneSession->GetFocusable() || !IsSessionVisibleForeground(sceneSession)) {
4560 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
4561 return WSError::WS_DO_NOTHING;
4562 }
4563 if (!sceneSession->IsFocusedOnShow()) {
4564 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4565 return WSError::WS_DO_NOTHING;
4566 }
4567 if (!sceneSession->IsFocusableOnShow() &&
4568 (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
4569 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
4570 return WSError::WS_DO_NOTHING;
4571 }
4572
4573 // subwindow/dialog state block
4574 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4575 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4576 GetSceneSession(sceneSession->GetParentPersistentId()) &&
4577 !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
4578 TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
4579 sceneSession->GetParentPersistentId());
4580 return WSError::WS_DO_NOTHING;
4581 }
4582 // specific block
4583 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
4584 if (specificCheckRet != WSError::WS_OK) {
4585 return specificCheckRet;
4586 }
4587
4588 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4589 needBlockNotifyFocusStatusUntilForeground_ = false;
4590 ShiftFocus(sceneSession, reason);
4591 return WSError::WS_OK;
4592 }
4593
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)4594 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
4595 {
4596 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
4597 if (persistentId == INVALID_SESSION_ID) {
4598 WLOGFE("id is invalid");
4599 return WSError::WS_ERROR_INVALID_SESSION;
4600 }
4601 auto focusedSession = GetSceneSession(focusedSessionId_);
4602 if (persistentId != focusedSessionId_ &&
4603 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
4604 TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
4605 return WSError::WS_DO_NOTHING;
4606 }
4607 // if pop menu created by desktop request unfocus, back to desktop
4608 auto lastSession = GetSceneSession(lastFocusedSessionId_);
4609 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
4610 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
4611 RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
4612 TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
4613 return WSError::WS_OK;
4614 }
4615 auto nextSession = GetNextFocusableSession(persistentId);
4616 if (nextSession == nullptr) {
4617 DumpAllSessionFocusableInfo(persistentId);
4618 }
4619
4620 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4621 needBlockNotifyFocusStatusUntilForeground_ = false;
4622
4623 if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
4624 return WSError::WS_OK;
4625 }
4626
4627 return ShiftFocus(nextSession, reason);
4628 }
4629
RequestAllAppSessionUnfocusInner()4630 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
4631 {
4632 TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
4633 auto focusedSession = GetSceneSession(focusedSessionId_);
4634 if (!focusedSession) {
4635 TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
4636 return WSError::WS_DO_NOTHING;
4637 }
4638 if (!focusedSession->IsAppSession()) {
4639 WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
4640 return WSError::WS_DO_NOTHING;
4641 }
4642 auto nextSession = GetTopFocusableNonAppSession();
4643
4644 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4645 needBlockNotifyFocusStatusUntilForeground_ = false;
4646 return ShiftFocus(nextSession, FocusChangeReason::WIND);
4647 }
4648
RequestFocusBasicCheck(int32_t persistentId)4649 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
4650 {
4651 // basic focus rule
4652 if (persistentId == INVALID_SESSION_ID) {
4653 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
4654 return WSError::WS_ERROR_INVALID_SESSION;
4655 }
4656 if (persistentId == focusedSessionId_) {
4657 TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
4658 return WSError::WS_DO_NOTHING;
4659 }
4660 return WSError::WS_OK;
4661 }
4662
4663 /**
4664 * @note @window.focus
4665 * When high zOrder System Session unfocus, check if the last focused app window can focus.
4666 */
CheckLastFocusedAppSessionFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & nextSession)4667 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
4668 sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
4669 {
4670 if (focusedSession == nullptr || nextSession == nullptr) {
4671 return false;
4672 }
4673
4674 TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
4675 lastFocusedAppSessionId_, nextSession->GetPersistentId());
4676
4677 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
4678 return false;
4679 }
4680
4681 if (!focusedSession->IsSystemSessionAboveApp()) {
4682 return false;
4683 }
4684
4685 auto mode = nextSession->GetWindowMode();
4686 // only when next session is app, and in split or floation
4687 if (nextSession->IsAppSession() &&
4688 (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
4689 mode == WindowMode::WINDOW_MODE_FLOATING)) {
4690 if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
4691 WSError::WS_OK) {
4692 return true;
4693 }
4694 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
4695 }
4696 return false;
4697 }
4698
4699 /**
4700 * When switching focus, check if the blockingType window has been traversed downwards.
4701 *
4702 * @return true: traversed downwards, false: not.
4703 */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession> & requestSceneSession,sptr<SceneSession> & focusedSession,bool includingAppSession)4704 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
4705 sptr<SceneSession>& focusedSession, bool includingAppSession)
4706 {
4707 uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
4708 uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
4709 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
4710 requestSessionZOrder, focusedSessionZOrder);
4711 if (requestSessionZOrder < focusedSessionZOrder) {
4712 auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
4713 includingAppSession);
4714 uint32_t topNearestBlockingZOrder = 0;
4715 if (topNearestBlockingFocusSession) {
4716 topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
4717 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
4718 topNearestBlockingZOrder: %{public}d", requestSessionZOrder, focusedSessionZOrder,
4719 topNearestBlockingZOrder);
4720 }
4721 if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) {
4722 TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted");
4723 return true;
4724 }
4725 }
4726 TLOGD(WmsLogTag::WMS_FOCUS, "not through");
4727 return false;
4728 }
4729
CheckTopmostWindowFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & sceneSession)4730 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
4731 {
4732 bool isFocusedMainSessionTopmost =
4733 focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
4734 auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
4735 bool isFocusedSessionParentTopmost = parentSession &&
4736 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
4737 if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
4738 (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
4739 return true;
4740 }
4741 return false;
4742 }
4743
CheckRequestFocusImmdediately(sptr<SceneSession> & sceneSession)4744 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
4745 {
4746 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4747 (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
4748 (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
4749 ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
4750 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
4751 return true;
4752 }
4753 return false;
4754 }
4755
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)4756 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
4757 const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
4758 {
4759 if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
4760 focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
4761 return false;
4762 }
4763 if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
4764 return false;
4765 }
4766 return sceneSession->GetZOrder() < focusedSession->GetZOrder();
4767 }
4768
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)4769 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
4770 FocusChangeReason reason)
4771 {
4772 TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
4773 int32_t persistentId = sceneSession->GetPersistentId();
4774 if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
4775 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
4776 return WSError::WS_ERROR_INVALID_OPERATION;
4777 }
4778 // dialog get focus
4779 if (CheckRequestFocusImmdediately(sceneSession)) {
4780 return WSError::WS_DO_NOTHING;
4781 }
4782 // blocking-type session will block lower zOrder request focus
4783 auto focusedSession = GetSceneSession(focusedSessionId_);
4784 if (focusedSession) {
4785 TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d", reason,
4786 byForeground);
4787 if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
4788 // return ok if focused session is topmost
4789 return WSError::WS_OK;
4790 }
4791 if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
4792 sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
4793 TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
4794 byForeground = false;
4795 }
4796 if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, true)) {
4797 TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
4798 return WSError::WS_DO_NOTHING;
4799 }
4800 if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
4801 !byForeground) {
4802 if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
4803 && focusedSession->IsAppSession()) {
4804 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
4805 return WSError::WS_OK;
4806 }
4807 }
4808 bool isBlockingType = focusedSession->IsAppSession() ||
4809 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
4810 // temp check
4811 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
4812 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
4813 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
4814 persistentId);
4815 return WSError::WS_DO_NOTHING;
4816 }
4817 // desktop click temp check
4818 if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
4819 TLOGW(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
4820 return WSError::WS_DO_NOTHING;
4821 }
4822 }
4823 return WSError::WS_OK;
4824 }
4825
CheckParentSessionVisible(const sptr<SceneSession> & session)4826 bool SceneSessionManager::CheckParentSessionVisible(const sptr<SceneSession>& session)
4827 {
4828 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
4829 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4830 GetSceneSession(session->GetParentPersistentId()) &&
4831 !IsSessionVisibleForeground(GetSceneSession(session->GetParentPersistentId()))) {
4832 return false;
4833 }
4834 return true;
4835 }
4836
DumpAllSessionFocusableInfo(int32_t persistentId)4837 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
4838 {
4839 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
4840 auto func = [this](sptr<SceneSession> session) {
4841 if (session == nullptr) {
4842 return false;
4843 }
4844 bool parentVisible = CheckParentSessionVisible(session);
4845 bool sessionVisible = IsSessionVisible(session);
4846 TLOGI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
4847 "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
4848 session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
4849 session->GetFocusable(), sessionVisible, parentVisible);
4850 return false;
4851 };
4852 TraverseSessionTree(func, true);
4853 }
4854
GetNextFocusableSession(int32_t persistentId)4855 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
4856 {
4857 TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
4858 bool previousFocusedSessionFound = false;
4859 sptr<SceneSession> ret = nullptr;
4860 auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
4861 if (session == nullptr) {
4862 return false;
4863 }
4864 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
4865 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
4866 return false;
4867 }
4868 if (previousFocusedSessionFound && session->GetFocusable() &&
4869 IsSessionVisibleForeground(session) && CheckParentSessionVisible(session)) {
4870 ret = session;
4871 return true;
4872 }
4873 if (session->GetPersistentId() == persistentId) {
4874 previousFocusedSessionFound = true;
4875 }
4876 return false;
4877 };
4878 TraverseSessionTree(func, true);
4879 return ret;
4880 }
4881
4882 /**
4883 * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
4884 * and it is the closest;
4885 */
GetTopNearestBlockingFocusSession(uint32_t zOrder,bool includingAppSession)4886 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
4887 {
4888 sptr<SceneSession> ret = nullptr;
4889 auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
4890 if (session == nullptr) {
4891 return false;
4892 }
4893 uint32_t sessionZOrder = session->GetZOrder();
4894 if (sessionZOrder <= zOrder) { // must be above the target session
4895 return false;
4896 }
4897 if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4898 TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
4899 return false;
4900 }
4901 auto parentSession = GetSceneSession(session->GetParentPersistentId());
4902 if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
4903 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
4904 parentSession->IsTopmost()) {
4905 TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
4906 return false;
4907 }
4908 bool isPhoneOrPad = systemConfig_.uiType_ == UI_TYPE_PHONE || systemConfig_.uiType_ == UI_TYPE_PAD;
4909 bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
4910 (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
4911 (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
4912 if (IsSessionVisibleForeground(session) && isBlockingType) {
4913 ret = session;
4914 return true;
4915 }
4916 return false;
4917 };
4918 TraverseSessionTree(func, false);
4919 return ret;
4920 }
4921
GetTopFocusableNonAppSession()4922 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
4923 {
4924 TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
4925 sptr<SceneSession> ret = nullptr;
4926 auto func = [this, &ret](sptr<SceneSession> session) {
4927 if (session == nullptr) {
4928 return false;
4929 }
4930 if (session->IsAppSession()) {
4931 return true;
4932 }
4933 if (session->GetFocusable() && IsSessionVisibleForeground(session)) {
4934 ret = session;
4935 }
4936 return false;
4937 };
4938 TraverseSessionTree(func, false);
4939 return ret;
4940 }
4941
SetShiftFocusListener(const ProcessShiftFocusFunc & func)4942 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
4943 {
4944 TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
4945 shiftFocusFunc_ = func;
4946 }
4947
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)4948 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
4949 {
4950 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
4951 notifySCBAfterFocusedFunc_ = func;
4952 }
4953
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)4954 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
4955 {
4956 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
4957 notifySCBAfterUnfocusedFunc_ = func;
4958 }
4959
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)4960 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
4961 {
4962 WLOGFD("SetCallingSessionIdSessionListenser");
4963 callingSessionIdChangeFunc_ = func;
4964 }
4965
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)4966 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
4967 {
4968 WLOGFD("SetStartUIAbilityErrorListener");
4969 startUIAbilityErrorFunc_ = func;
4970 }
4971
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)4972 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
4973 const AbilityManagerCollaboratorRegisteredFunc& func)
4974 {
4975 auto task = [this, func] {
4976 abilityManagerCollaboratorRegisteredFunc_ = func;
4977 };
4978 taskScheduler_->PostAsyncTask(task, __func__);
4979 }
4980
ShiftFocus(sptr<SceneSession> & nextSession,FocusChangeReason reason)4981 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)
4982 {
4983 // unfocus
4984 int32_t focusedId = focusedSessionId_;
4985 auto focusedSession = GetSceneSession(focusedSessionId_);
4986 UpdateFocusStatus(focusedSession, false);
4987 // focus
4988 int32_t nextId = INVALID_SESSION_ID;
4989 if (nextSession == nullptr) {
4990 std::string sessionLog(GetAllSessionFocusInfo());
4991 TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
4992 focusedSessionId_, sessionLog.c_str());
4993 } else {
4994 nextId = nextSession->GetPersistentId();
4995 }
4996 UpdateFocusStatus(nextSession, true);
4997 if (shiftFocusFunc_ != nullptr) {
4998 shiftFocusFunc_(nextId);
4999 }
5000 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5001 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5002 AnomalyDetection::FocusCheckProcess(focusedId, nextId);
5003 if (!scbPrevFocus && scbCurrFocus) {
5004 if (notifySCBAfterFocusedFunc_ != nullptr) {
5005 notifySCBAfterFocusedFunc_();
5006 }
5007 } else if (scbPrevFocus && !scbCurrFocus) {
5008 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5009 notifySCBAfterUnfocusedFunc_();
5010 }
5011 }
5012 TLOGI(WmsLogTag::WMS_FOCUS, "ShiftFocus, focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5013 focusedId, nextId, reason);
5014 return WSError::WS_OK;
5015 }
5016
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5017 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5018 {
5019 if (sceneSession == nullptr) {
5020 if (isFocused) {
5021 SetFocusedSessionId(INVALID_SESSION_ID);
5022 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5023 }
5024 return;
5025 }
5026 TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5027 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5028 // set focused
5029 if (isFocused) {
5030 SetFocusedSessionId(sceneSession->GetPersistentId());
5031 if (sceneSession->IsAppOrLowerSystemSession()) {
5032 lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5033 }
5034 }
5035 sceneSession->UpdateFocus(isFocused);
5036 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5037 NotifyFocusStatus(sceneSession, isFocused);
5038 }
5039 }
5040
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5041 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5042 {
5043 if (sceneSession == nullptr) {
5044 WLOGFE("[WMSComm]session is nullptr");
5045 if (isFocused) {
5046 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5047 NotifyUnFocusedByMission(prevSession);
5048 }
5049 return;
5050 }
5051 int32_t persistentId = sceneSession->GetPersistentId();
5052
5053 TLOGI(WmsLogTag::WMS_FOCUS,
5054 "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5055 sceneSession->GetSessionInfo().bundleName_.c_str(),
5056 sceneSession->GetSessionInfo().abilityName_.c_str(),
5057 sceneSession->GetWindowNameAllType().c_str(),
5058 persistentId, isFocused);
5059 if (isFocused) {
5060 if (IsSessionVisibleForeground(sceneSession)) {
5061 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5062 }
5063 UpdateBrightness(focusedSessionId_);
5064 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5065 }
5066 // notify window manager
5067 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5068 sceneSession->GetWindowId(),
5069 static_cast<DisplayId>(0),
5070 sceneSession->GetCallingPid(),
5071 sceneSession->GetCallingUid(),
5072 sceneSession->GetWindowType(),
5073 sceneSession->GetAbilityToken()
5074 );
5075 SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5076 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5077 sceneSession->NotifyFocusStatus(isFocused);
5078 // notify listenerController
5079 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5080 if (isFocused && MissionChanged(prevSession, sceneSession)) {
5081 NotifyFocusStatusByMission(prevSession, sceneSession);
5082 }
5083 }
5084
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)5085 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5086 const std::string& reason)
5087 {
5088 uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5089 nlohmann::json payload;
5090 payload.emplace("uid", uid);
5091 payload.emplace("bundleName", bundleName);
5092 payload.emplace("reason", reason);
5093 nlohmann::json reply;
5094 int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5095 return ret;
5096 }
5097
NotifyFocusStatusByMission(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5098 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5099 {
5100 if (listenerController_ != nullptr) {
5101 if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5102 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", prevSession->GetMissionId());
5103 listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5104 }
5105 if (currSession && !currSession->GetSessionInfo().isSystem_) {
5106 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionFocused, id: %{public}d", currSession->GetMissionId());
5107 listenerController_->NotifySessionFocused(currSession->GetMissionId());
5108 }
5109 }
5110 }
5111
NotifyUnFocusedByMission(sptr<SceneSession> & sceneSession)5112 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5113 {
5114 if (listenerController_ == nullptr) {
5115 return;
5116 }
5117 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5118 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", sceneSession->GetMissionId());
5119 listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5120 }
5121 }
5122
MissionChanged(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5123 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5124 {
5125 if (prevSession == nullptr && currSession == nullptr) {
5126 return false;
5127 }
5128 if (prevSession == nullptr || currSession == nullptr) {
5129 return true;
5130 }
5131 return prevSession->GetMissionId() != currSession->GetMissionId();
5132 }
5133
GetAllSessionFocusInfo()5134 std::string SceneSessionManager::GetAllSessionFocusInfo()
5135 {
5136 std::ostringstream os;
5137 auto func = [&os](sptr<SceneSession> session) {
5138 if (session == nullptr) {
5139 WLOGE("sceneSession is nullptr");
5140 return false;
5141 }
5142 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5143 " ,focusable: "<< session->GetFocusable() << ";";
5144 return false;
5145 };
5146 TraverseSessionTree(func, true);
5147 return os.str();
5148 }
5149
UpdateFocus(int32_t persistentId,bool isFocused)5150 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5151 {
5152 auto task = [this, persistentId, isFocused]() {
5153 // notify session and client
5154 auto sceneSession = GetSceneSession(persistentId);
5155 if (sceneSession == nullptr) {
5156 WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5157 return WSError::WS_ERROR_INVALID_WINDOW;
5158 }
5159 WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5160 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5161 // focusId change
5162 if (isFocused) {
5163 SetFocusedSessionId(persistentId);
5164 UpdateBrightness(focusedSessionId_);
5165 FocusIDChange(persistentId, sceneSession);
5166 } else if (persistentId == GetFocusedSessionId()) {
5167 SetFocusedSessionId(INVALID_SESSION_ID);
5168 }
5169 // notify window manager
5170 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5171 sceneSession->GetWindowId(),
5172 static_cast<DisplayId>(0),
5173 sceneSession->GetCallingPid(),
5174 sceneSession->GetCallingUid(),
5175 sceneSession->GetWindowType(),
5176 sceneSession->GetAbilityToken()
5177 );
5178 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5179 WSError res = WSError::WS_OK;
5180 res = sceneSession->UpdateFocus(isFocused);
5181 if (res != WSError::WS_OK) {
5182 return res;
5183 }
5184 WLOGFI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5185 sceneSession->GetSessionInfo().isSystem_);
5186 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
5187 if (isFocused) {
5188 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
5189 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5190 } else {
5191 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5192 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5193 }
5194 }
5195 return WSError::WS_OK;
5196 };
5197
5198 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5199 return WSError::WS_OK;
5200 }
5201
UpdateWindowMode(int32_t persistentId,int32_t windowMode)5202 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5203 {
5204 WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
5205 auto sceneSession = GetSceneSession(persistentId);
5206 if (sceneSession == nullptr) {
5207 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
5208 return WSError::WS_ERROR_INVALID_WINDOW;
5209 }
5210 WindowMode mode = static_cast<WindowMode>(windowMode);
5211 return sceneSession->UpdateWindowMode(mode);
5212 }
5213
5214 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)5215 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
5216 MMI::PointerEvent::PointerItem& pointerItem)
5217 {
5218 struct PointerEventData {
5219 double x;
5220 double y;
5221 uint64_t time;
5222 } pointerEventData = {
5223 .x = pointerItem.GetDisplayX(),
5224 .y = pointerItem.GetDisplayY(),
5225 .time = pointerEvent->GetActionTime()
5226 };
5227
5228 const uint32_t MAX_HMAC_SIZE = 64;
5229 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
5230 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
5231 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
5232 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
5233 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
5234 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
5235 }
5236 }
5237 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
5238
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)5239 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
5240 {
5241 if (!pointerEvent) {
5242 WLOGFE("pointerEvent is null");
5243 return WSError::WS_ERROR_NULLPTR;
5244 }
5245 MMI::PointerEvent::PointerItem pointerItem;
5246 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
5247 WLOGFE("Failed to get pointerItem");
5248 return WSError::WS_ERROR_INVALID_PARAM;
5249 }
5250 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
5251 FillSecCompEnhanceData(pointerEvent, pointerItem);
5252 #endif
5253 TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d,action=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
5254 pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
5255 pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
5256 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
5257 return WSError::WS_OK;
5258 }
5259
SetScreenLocked(const bool isScreenLocked)5260 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
5261 {
5262 isScreenLocked_ = isScreenLocked;
5263 DeleteStateDetectTask();
5264 }
5265
DeleteStateDetectTask()5266 void SceneSessionManager::DeleteStateDetectTask()
5267 {
5268 if (!IsScreenLocked()) {
5269 return;
5270 }
5271 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5272 for (auto iter : sceneSessionMap_) {
5273 auto& session = iter.second;
5274 if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
5275 taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
5276 DetectTaskInfo detectTaskInfo;
5277 session->SetDetectTaskInfo(detectTaskInfo);
5278 }
5279 }
5280 }
5281
IsScreenLocked() const5282 bool SceneSessionManager::IsScreenLocked() const
5283 {
5284 return isScreenLocked_;
5285 }
5286
RegisterWindowChanged(const WindowChangedFunc & func)5287 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
5288 {
5289 WindowChangedFunc_ = func;
5290 }
5291
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)5292 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
5293 const std::unordered_set<std::string>& privacyBundles)
5294 {
5295 bool needNotify = false;
5296 static int reSendTimes = MAX_RESEND_TIMES;
5297 std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
5298 do {
5299 if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
5300 TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
5301 needNotify = !privacyBundles.empty();
5302 break;
5303 }
5304 const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
5305 if (lastPrivacyBundles.size() != privacyBundles.size()) {
5306 TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
5307 lastPrivacyBundles.size(), privacyBundles.size());
5308 needNotify = true;
5309 break;
5310 }
5311 for (const auto& bundle : lastPrivacyBundles) {
5312 if (privacyBundles.find(bundle) == privacyBundles.end()) {
5313 needNotify = true;
5314 break;
5315 }
5316 }
5317 } while (false);
5318
5319 TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
5320 displayId, needNotify);
5321 if (needNotify) {
5322 reSendTimes = MAX_RESEND_TIMES;
5323 privacyBundleMap_[displayId] = privacyBundles;
5324 } else if (reSendTimes > 0) {
5325 needNotify = true;
5326 reSendTimes--;
5327 privacyBundleMap_[displayId] = privacyBundles;
5328 }
5329 return needNotify;
5330 }
5331
UpdatePrivateStateAndNotify(uint32_t persistentId)5332 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
5333 {
5334 auto sceneSession = GetSceneSession(persistentId);
5335 if (sceneSession == nullptr) {
5336 TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
5337 return;
5338 }
5339
5340 auto sessionProperty = sceneSession->GetSessionProperty();
5341 if (sessionProperty == nullptr) {
5342 TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
5343 return;
5344 }
5345 auto displayId = sessionProperty->GetDisplayId();
5346 std::unordered_set<std::string> privacyBundleList;
5347 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5348 if (!JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
5349 return;
5350 }
5351
5352 std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
5353 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5354 !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
5355 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
5356 if (!bundleListForNotify.empty()) {
5357 TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
5358 }
5359 for (const auto& bundle : bundleListForNotify) {
5360 TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
5361 displayId, bundle.c_str());
5362 }
5363 }
5364
UpdatePrivateStateAndNotifyForAllScreens()5365 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
5366 {
5367 auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
5368 for (auto& iter : screenProperties) {
5369 auto displayId = iter.first;
5370 std::unordered_set<std::string> privacyBundleList;
5371 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5372
5373 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5374 !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
5375 }
5376 }
5377
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)5378 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
5379 std::unordered_set<std::string>& privacyBundles)
5380 {
5381 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5382 for (const auto& item : sceneSessionMap_) {
5383 sptr<SceneSession> sceneSession = item.second;
5384 if (sceneSession == nullptr) {
5385 TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
5386 continue;
5387 }
5388 auto sessionProperty = sceneSession->GetSessionProperty();
5389 if (sessionProperty == nullptr) {
5390 TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
5391 continue;
5392 }
5393 auto currentDisplayId = sessionProperty->GetDisplayId();
5394 if (displayId != currentDisplayId) {
5395 continue;
5396 }
5397 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5398 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
5399 if (isForeground && sceneSession->GetParentSession() != nullptr) {
5400 isForeground = isForeground &&
5401 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
5402 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
5403 }
5404 bool isPrivate = sessionProperty->GetPrivacyMode() ||
5405 sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
5406 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
5407 if ((isForeground || IsSystemWindowVisible) && isPrivate) {
5408 if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
5409 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
5410 } else {
5411 TLOGD(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
5412 privacyBundles.insert(sceneSession->GetWindowName());
5413 }
5414 }
5415 }
5416 }
5417
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5418 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5419 {
5420 NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
5421 this->OnSessionStateChange(persistentId, state);
5422 };
5423 if (sceneSession == nullptr) {
5424 WLOGFE("session is nullptr");
5425 return;
5426 }
5427 sceneSession->SetSessionStateChangeNotifyManagerListener(func);
5428 WLOGFD("RegisterSessionStateChangeFunc success");
5429 }
5430
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5431 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5432 {
5433 wptr<SceneSessionManager> weakSessionManager = this;
5434 NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
5435 auto sceneSessionManager = weakSessionManager.promote();
5436 if (sceneSessionManager == nullptr) {
5437 return;
5438 }
5439 sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
5440 };
5441 if (sceneSession == nullptr) {
5442 WLOGFE("session is nullptr");
5443 return;
5444 }
5445 sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
5446 }
5447
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)5448 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5449 {
5450 NotifyRequestFocusStatusNotifyManagerFunc func =
5451 [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
5452 this->RequestFocusStatus(persistentId, isFocused, byForeground, reason);
5453 };
5454 if (sceneSession == nullptr) {
5455 WLOGFE("session is nullptr");
5456 return;
5457 }
5458 sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
5459 WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
5460 }
5461
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)5462 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
5463 {
5464 GetStateFromManagerFunc func = [this](const ManagerState key) {
5465 switch (key)
5466 {
5467 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
5468 return this->IsScreenLocked();
5469 break;
5470 default:
5471 return false;
5472 break;
5473 }
5474 };
5475 if (sceneSession == nullptr) {
5476 WLOGFE("session is nullptr");
5477 return;
5478 }
5479 sceneSession->SetGetStateFromManagerListener(func);
5480 WLOGFD("RegisterGetStateFromManagerFunc success");
5481 }
5482
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)5483 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5484 {
5485 SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
5486 const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
5487 if (sceneSession == nullptr || property == nullptr) {
5488 TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
5489 return;
5490 }
5491 switch (action) {
5492 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
5493 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
5494 break;
5495 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
5496 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
5497 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
5498 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
5499 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
5500 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
5501 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5502 break;
5503 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
5504 SetBrightness(sceneSession, property->GetBrightness());
5505 break;
5506 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
5507 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
5508 UpdatePrivateStateAndNotify(property->GetPersistentId());
5509 break;
5510 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
5511 CheckAndNotifyWaterMarkChangedResult();
5512 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5513 break;
5514 case WSPropertyChangeAction::ACTION_UPDATE_MODE:
5515 if (sceneSession->GetSessionProperty() != nullptr) {
5516 ProcessWindowModeType();
5517 }
5518 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5519 break;
5520 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5521 HandleHideNonSystemFloatingWindows(property, sceneSession);
5522 break;
5523 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
5524 FlushWindowInfoToMMI();
5525 break;
5526 default:
5527 break;
5528 }
5529 };
5530 if (sceneSession != nullptr) {
5531 sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
5532 }
5533 }
5534
OnSessionStateChange(int32_t persistentId,const SessionState & state)5535 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
5536 int32_t persistentId, const SessionState& state)
5537 {
5538 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
5539 WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
5540 auto sceneSession = GetSceneSession(persistentId);
5541 if (sceneSession == nullptr) {
5542 WLOGFD("session is nullptr");
5543 return;
5544 }
5545 switch (state) {
5546 case SessionState::STATE_FOREGROUND:
5547 ProcessFocusWhenForeground(sceneSession);
5548 if (!IsSessionVisibleForeground(sceneSession)) {
5549 sceneSession->SetPostProcessProperty(true);
5550 break;
5551 }
5552 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
5553 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
5554 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
5555 UpdatePrivateStateAndNotify(persistentId);
5556 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5557 ProcessSubSessionForeground(sceneSession);
5558 }
5559 break;
5560 case SessionState::STATE_BACKGROUND:
5561 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
5562 RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
5563 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
5564 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
5565 HandleKeepScreenOn(sceneSession, false);
5566 UpdatePrivateStateAndNotify(persistentId);
5567 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5568 ProcessSubSessionBackground(sceneSession);
5569 }
5570 break;
5571 default:
5572 break;
5573 }
5574 ProcessWindowModeType();
5575 }
5576
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)5577 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
5578 {
5579 auto persistentId = sceneSession->GetPersistentId();
5580 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5581 persistentId == focusedSessionId_) {
5582 if (needBlockNotifyFocusStatusUntilForeground_) {
5583 needBlockNotifyUnfocusStatus_ = false;
5584 needBlockNotifyFocusStatusUntilForeground_ = false;
5585 NotifyFocusStatus(sceneSession, true);
5586 }
5587 } else if (!sceneSession->IsFocusedOnShow()) {
5588 sceneSession->SetFocusedOnShow(true);
5589 } else {
5590 if (Session::IsScbCoreEnabled()) {
5591 ProcessFocusWhenForegroundScbCore(sceneSession);
5592 } else {
5593 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5594 }
5595 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5596 }
5597 }
5598
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)5599 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
5600 {
5601 if (sceneSession == nullptr) {
5602 TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
5603 return;
5604 }
5605 if (sceneSession->IsFocusableOnShow()) {
5606 if (IsSessionVisibleForeground(sceneSession)) {
5607 RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
5608 } else {
5609 PostProcessFocusState state = {true, true, FocusChangeReason::APP_FOREGROUND};
5610 sceneSession->SetPostProcessFocusState(state);
5611 }
5612 } else {
5613 TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
5614 sceneSession->GetPersistentId());
5615 }
5616 }
5617
ProcessWindowModeType()5618 void SceneSessionManager::ProcessWindowModeType()
5619 {
5620 if (isScreenLocked_) {
5621 return;
5622 }
5623 NotifyRSSWindowModeTypeUpdate();
5624 }
5625
IsSmallFoldProduct()5626 static bool IsSmallFoldProduct()
5627 {
5628 static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
5629 if (foldScreenType.empty()) {
5630 TLOGE(WmsLogTag::DEFAULT, "foldScreenType is empty");
5631 return false;
5632 }
5633 return foldScreenType[0] == '2';
5634 }
5635
IsInSecondaryScreen(const sptr<SceneSession> & sceneSession)5636 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
5637 {
5638 auto sessionProperty = sceneSession->GetSessionProperty();
5639 if (sessionProperty == nullptr) {
5640 TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
5641 return false;
5642 }
5643 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5644 return sessionProperty->GetDisplayId() != defaultScreenId;
5645 }
5646
CheckWindowModeType()5647 WindowModeType SceneSessionManager::CheckWindowModeType()
5648 {
5649 bool inSplit = false;
5650 bool inFloating = false;
5651 bool fullScreen = false;
5652 bool isSmallFold = IsSmallFoldProduct();
5653 {
5654 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5655 for (const auto& session : sceneSessionMap_) {
5656 if (session.second == nullptr ||
5657 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
5658 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
5659 continue;
5660 }
5661 if (isSmallFold && IsInSecondaryScreen(session.second)) {
5662 continue;
5663 }
5664 auto mode = session.second->GetWindowMode();
5665 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
5666 inSplit = true;
5667 }
5668 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
5669 inFloating = true;
5670 }
5671 if (WindowHelper::IsFullScreenWindow(mode)) {
5672 fullScreen = true;
5673 }
5674 }
5675 }
5676
5677 WindowModeType type;
5678 if (inSplit) {
5679 if (inFloating) {
5680 type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
5681 } else {
5682 type = WindowModeType::WINDOW_MODE_SPLIT;
5683 }
5684 } else {
5685 if (inFloating) {
5686 if (fullScreen) {
5687 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
5688 } else {
5689 type = WindowModeType::WINDOW_MODE_FLOATING;
5690 }
5691 } else if (fullScreen) {
5692 type = WindowModeType::WINDOW_MODE_FULLSCREEN;
5693 } else {
5694 type = WindowModeType::WINDOW_MODE_OTHER;
5695 }
5696 }
5697 return type;
5698 }
5699
NotifyRSSWindowModeTypeUpdate()5700 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
5701 {
5702 WindowModeType type = CheckWindowModeType();
5703 if (lastWindowModeType_ == type) {
5704 return;
5705 }
5706 lastWindowModeType_ = type;
5707 TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
5708 static_cast<uint8_t>(type));
5709 SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
5710 }
5711
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)5712 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
5713 {
5714 if (sceneSession == nullptr) {
5715 WLOGFD("session is nullptr");
5716 return;
5717 }
5718 std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
5719 for (const auto& subSession : sceneSession->GetSubSession()) {
5720 if (subSession == nullptr) {
5721 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
5722 continue;
5723 }
5724 if (subSession->IsTopmost()) {
5725 modalVec.push_back(subSession);
5726 TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
5727 continue;
5728 }
5729 const auto& state = subSession->GetSessionState();
5730 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5731 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
5732 continue;
5733 }
5734 RequestSessionFocus(subSession->GetPersistentId(), true);
5735 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5736 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
5737 }
5738
5739 for (const auto& modal : modalVec) {
5740 if (modal == nullptr) {
5741 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
5742 continue;
5743 }
5744 const auto& state = modal->GetSessionState();
5745 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5746 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
5747 continue;
5748 }
5749 auto modalSession = GetSceneSession(modal->GetPersistentId());
5750 if (modalSession == nullptr) {
5751 TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
5752 continue;
5753 }
5754 NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5755 if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
5756 needBlockNotifyUnfocusStatus_ = false;
5757 needBlockNotifyFocusStatusUntilForeground_ = false;
5758 NotifyFocusStatus(modalSession, true);
5759 }
5760 HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
5761 }
5762 }
5763
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5764 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5765 {
5766 // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
5767 sptr<SceneSession> mainSession = nullptr;
5768 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5769 mainSession = sceneSession;
5770 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5771 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5772 }
5773 if (mainSession == nullptr) {
5774 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5775 return WSError::WS_DO_NOTHING;
5776 }
5777
5778 std::vector<sptr<SceneSession>> topmostVec;
5779 for (auto subSession : mainSession->GetSubSession()) {
5780 if (subSession && subSession->IsTopmost()) {
5781 topmostVec.push_back(subSession);
5782 }
5783 }
5784 if (std::find_if(topmostVec.begin(), topmostVec.end(),
5785 [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5786 != topmostVec.end()) {
5787 TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
5788 return WSError::WS_OK;
5789 }
5790 WSError ret = WSError::WS_DO_NOTHING;
5791 for (auto topmostSession : topmostVec) {
5792 if (topmostSession == nullptr) {
5793 continue;
5794 }
5795 // no need to consider order, since rule of zOrder
5796 if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
5797 ret = WSError::WS_OK;
5798 }
5799 }
5800 return ret;
5801 }
5802
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5803 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5804 {
5805 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
5806 sptr<SceneSession> mainSession = nullptr;
5807 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5808 mainSession = sceneSession;
5809 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5810 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5811 }
5812 if (mainSession == nullptr) {
5813 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5814 return WSError::WS_DO_NOTHING;
5815 }
5816 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
5817 if (std::find_if(dialogVec.begin(), dialogVec.end(),
5818 [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5819 != dialogVec.end()) {
5820 TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
5821 return WSError::WS_OK;
5822 }
5823 WSError ret = WSError::WS_DO_NOTHING;
5824 for (auto dialog : dialogVec) {
5825 if (dialog == nullptr) {
5826 continue;
5827 }
5828 // no need to consider order, since rule of zOrder
5829 if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
5830 ret = WSError::WS_OK;
5831 }
5832 }
5833 return ret;
5834 }
5835
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)5836 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
5837 {
5838 if (sceneSession == nullptr) {
5839 WLOGFD("session is nullptr");
5840 return;
5841 }
5842 for (const auto& subSession : sceneSession->GetSubSession()) {
5843 if (subSession == nullptr) {
5844 WLOGFD("sub session is nullptr");
5845 continue;
5846 }
5847 const auto& state = subSession->GetSessionState();
5848 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5849 WLOGFD("sub session is not active");
5850 continue;
5851 }
5852 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5853 HandleKeepScreenOn(subSession, false);
5854 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
5855 }
5856 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
5857 for (const auto& dialog : dialogVec) {
5858 if (dialog == nullptr) {
5859 TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
5860 continue;
5861 }
5862 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
5863 if (dialogSession == nullptr) {
5864 TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
5865 continue;
5866 }
5867 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5868 HandleKeepScreenOn(dialogSession, false);
5869 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
5870 }
5871 for (const auto& toastSession : sceneSession->GetToastSession()) {
5872 if (toastSession == nullptr) {
5873 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
5874 continue;
5875 }
5876 const auto& state = toastSession->GetSessionState();
5877 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5878 continue;
5879 }
5880 NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
5881 HandleKeepScreenOn(toastSession, false);
5882 UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
5883 toastSession->SetActive(false);
5884 toastSession->BackgroundTask();
5885 }
5886 }
5887
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)5888 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
5889 const sptr<WindowSessionProperty>& property)
5890 {
5891 if (sceneSession == nullptr) {
5892 WLOGFD("session is nullptr");
5893 return WSError::WS_ERROR_NULLPTR;
5894 }
5895 auto sessionProperty = sceneSession->GetSessionProperty();
5896 if (sessionProperty == nullptr) {
5897 return WSError::WS_ERROR_NULLPTR;
5898 }
5899 uint32_t flags = property->GetWindowFlags();
5900 uint32_t oldFlags = sessionProperty->GetWindowFlags();
5901 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
5902 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
5903 !property->GetSystemCalling()) {
5904 WLOGFE("Set window flags permission denied");
5905 return WSError::WS_ERROR_NOT_SYSTEM_APP;
5906 }
5907 sessionProperty->SetWindowFlags(flags);
5908 CheckAndNotifyWaterMarkChangedResult();
5909 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
5910 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
5911 }
5912 WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
5913 return WSError::WS_OK;
5914 }
5915
CheckAndNotifyWaterMarkChangedResult()5916 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
5917 {
5918 bool currentWaterMarkShowState = false;
5919 {
5920 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5921 for (const auto& iter: sceneSessionMap_) {
5922 auto& session = iter.second;
5923 if (!session) {
5924 continue;
5925 }
5926 auto sessionProperty = session->GetSessionProperty();
5927 if (!sessionProperty) {
5928 continue;
5929 }
5930 bool hasWaterMark = sessionProperty->GetWindowFlags() &
5931 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
5932 bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
5933 if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
5934 currentWaterMarkShowState = true;
5935 break;
5936 }
5937 }
5938 if (combinedExtWindowFlags_.waterMarkFlag) {
5939 TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
5940 currentWaterMarkShowState = true;
5941 }
5942 }
5943 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
5944 lastWaterMarkShowState_ = currentWaterMarkShowState;
5945 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
5946 }
5947 }
5948
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)5949 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
5950 {
5951 WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
5952 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
5953 return WSError::WS_OK;
5954 }
5955
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const5956 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
5957 {
5958 if (!bundleMgr_) {
5959 WLOGFE("bundle manager is nullptr.");
5960 return;
5961 }
5962
5963 AAFwk::Want want;
5964 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
5965 auto uid = abilityInfo.uid;
5966 want.SetParam("uid", uid);
5967 bundleMgr_->ProcessPreload(want);
5968 }
5969
NotifyCompleteFirstFrameDrawing(int32_t persistentId)5970 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
5971 {
5972 auto scnSession = GetSceneSession(persistentId);
5973 if (scnSession == nullptr) {
5974 TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
5975 return;
5976 }
5977
5978 const auto& sessionInfo = scnSession->GetSessionInfo();
5979 if (IsAtomicServiceFreeInstall(sessionInfo)) {
5980 TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
5981 scnSession->GetPersistentId(), scnSession->GetWindowType());
5982 FillSessionInfo(scnSession);
5983 }
5984
5985 TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
5986 scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
5987 sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
5988 auto abilityInfoPtr = sessionInfo.abilityInfo;
5989 if (abilityInfoPtr == nullptr) {
5990 TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
5991 return;
5992 }
5993 if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
5994 !(abilityInfoPtr->excludeFromMissions)) {
5995 WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
5996 listenerController_->NotifySessionCreated(persistentId);
5997 }
5998
5999 if (eventHandler_ != nullptr) {
6000 auto task = [persistentId]() {
6001 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6002 };
6003 WLOGFI("Post CompleteFirstFrameDrawing task.");
6004 bool ret = eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6005 if (!ret) {
6006 WLOGFE("Report post first frame task failed. the task name is CompleteFirstFrameDrawing");
6007 }
6008 }
6009
6010 if (taskScheduler_ == nullptr) {
6011 return;
6012 }
6013 auto task = [this, abilityInfoPtr]() {
6014 ProcessPreload(*abilityInfoPtr);
6015 };
6016 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6017 }
6018
NotifySessionMovedToFront(int32_t persistentId)6019 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6020 {
6021 WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
6022 auto scnSession = GetSceneSession(persistentId);
6023 if (scnSession == nullptr) {
6024 WLOGFE("session is invalid with %{public}d", persistentId);
6025 return;
6026 }
6027 WLOGFI("NotifySessionMovedToFront, id: %{public}d, system: %{public}d", scnSession->GetPersistentId(),
6028 scnSession->GetSessionInfo().isSystem_);
6029 if (listenerController_ != nullptr &&
6030 !scnSession->GetSessionInfo().isSystem_ &&
6031 (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
6032 !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6033 listenerController_->NotifySessionMovedToFront(persistentId);
6034 }
6035 }
6036
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)6037 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6038 {
6039 WLOGFI("Enter label: %{public}s", label.c_str());
6040
6041 auto task = [this, &token, &label]() {
6042 auto sceneSession = FindSessionByToken(token);
6043 if (sceneSession == nullptr) {
6044 WLOGFI("fail to find session by token");
6045 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6046 }
6047 sceneSession->SetSessionLabel(label);
6048 WLOGFI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6049 sceneSession->GetSessionInfo().isSystem_);
6050 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
6051 WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6052 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6053 }
6054 return WSError::WS_OK;
6055 };
6056 return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6057 }
6058
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)6059 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6060 const std::shared_ptr<Media::PixelMap>& icon)
6061 {
6062 WLOGFI("Enter");
6063 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6064 WLOGFE("The caller is not system-app, can not use system-api");
6065 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6066 }
6067
6068 auto task = [this, &token, &icon]() {
6069 auto sceneSession = FindSessionByToken(token);
6070 if (sceneSession == nullptr) {
6071 WLOGFI("fail to find session by token");
6072 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6073 }
6074 sceneSession->SetSessionIcon(icon);
6075 WLOGFI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6076 sceneSession->GetSessionInfo().isSystem_);
6077 if (listenerController_ != nullptr &&
6078 !sceneSession->GetSessionInfo().isSystem_ &&
6079 (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
6080 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6081 WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6082 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6083 }
6084 return WSError::WS_OK;
6085 };
6086 return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6087 }
6088
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)6089 WSError SceneSessionManager::IsValidSessionIds(
6090 const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6091 {
6092 WLOGFI("Enter");
6093 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6094 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6095 auto search = sceneSessionMap_.find(sessionIds.at(i));
6096 if (search == sceneSessionMap_.end() || search->second == nullptr) {
6097 results.push_back(false);
6098 continue;
6099 }
6100 results.push_back(true);
6101 }
6102 return WSError::WS_OK;
6103 }
6104
RegisterSessionListener(const sptr<ISessionListener> & listener)6105 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6106 {
6107 WLOGFI("Enter");
6108 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6109 WLOGFE("The caller is not system-app, can not use system-api");
6110 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6111 }
6112 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6113 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6114 return WSError::WS_ERROR_INVALID_PERMISSION;
6115 }
6116 auto task = [this, &listener]() {
6117 WSError ret = WSError::WS_DO_NOTHING;
6118 if (listenerController_ != nullptr) {
6119 ret = listenerController_->AddSessionListener(listener);
6120 } else {
6121 WLOGFE("The listenerController is nullptr");
6122 }
6123
6124 // app continue report for distributed scheduled service
6125 SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6126 static_cast<int32_t>(ret));
6127
6128 return ret;
6129 };
6130 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6131 }
6132
UnRegisterSessionListener(const sptr<ISessionListener> & listener)6133 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6134 {
6135 WLOGFI("Enter");
6136 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6137 WLOGFE("The caller is not system-app, can not use system-api");
6138 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6139 }
6140 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6141 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6142 return WSError::WS_ERROR_INVALID_PERMISSION;
6143 }
6144 auto task = [this, &listener]() {
6145 if (listenerController_ != nullptr) {
6146 listenerController_->DelSessionListener(listener);
6147 return WSError::WS_OK;
6148 } else {
6149 WLOGFE("The listenerController is nullptr");
6150 return WSError::WS_DO_NOTHING;
6151 }
6152 };
6153 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6154 }
6155
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6156 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6157 std::vector<SessionInfoBean>& sessionInfos)
6158 {
6159 WLOGFI("Enter num max %{public}d", numMax);
6160 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6161 WLOGFE("The caller is not system-app, can not use system-api");
6162 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6163 }
6164 if (!SessionPermission::VerifySessionPermission()) {
6165 WLOGFE("The caller has not permission granted");
6166 return WSError::WS_ERROR_INVALID_PERMISSION;
6167 }
6168 auto task = [this, &deviceId, numMax, &sessionInfos]() {
6169 if (CheckIsRemote(deviceId)) {
6170 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6171 if (ret != ERR_OK) {
6172 return WSError::WS_ERROR_INVALID_PARAM;
6173 } else {
6174 return WSError::WS_OK;
6175 }
6176 }
6177 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6178 std::vector<sptr<SceneSession>> sceneSessionInfos;
6179 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6180 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6181 auto sceneSession = iter->second;
6182 if (sceneSession == nullptr) {
6183 WLOGFE("session is nullptr");
6184 continue;
6185 }
6186 auto sessionInfo = sceneSession->GetSessionInfo();
6187 if (sessionInfo.isSystem_) {
6188 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
6189 continue;
6190 }
6191 auto want = sessionInfo.want;
6192 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
6193 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6194 sceneSession->GetPersistentId());
6195 continue;
6196 }
6197 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
6198 break;
6199 }
6200 WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
6201 sessionInfo.bundleName_.c_str());
6202 sceneSessionInfos.emplace_back(sceneSession);
6203 }
6204 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
6205 };
6206 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
6207 }
6208
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)6209 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
6210 {
6211 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
6212 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
6213 TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
6214 return WSError::WS_ERROR_INVALID_PERMISSION;
6215 }
6216 if (pid < 0) {
6217 return WSError::WS_ERROR_INVALID_PARAM;
6218 }
6219 auto task = [this, pid, &windowStates] {
6220 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6221 for (const auto& [_, sceneSession] : sceneSessionMap_) {
6222 if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
6223 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6224 MainWindowState windowState;
6225 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
6226 windowState.isVisible_ = sceneSession->GetRSVisible();
6227 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
6228 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
6229 windowStates.emplace_back(windowState);
6230 }
6231 }
6232 return WSError::WS_OK;
6233 };
6234 return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
6235 }
6236
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6237 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
6238 std::vector<SessionInfoBean>& sessionInfos)
6239 {
6240 TLOGI(WmsLogTag::DEFAULT, "begin");
6241 int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
6242 if (result != ERR_OK) {
6243 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6244 return result;
6245 }
6246 return ERR_OK;
6247 }
6248
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6249 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
6250 int32_t persistentId, SessionInfoBean& sessionInfo)
6251 {
6252 WLOGFI("id %{public}d", persistentId);
6253 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6254 WLOGFE("The caller is not system-app, can not use system-api");
6255 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6256 }
6257 if (!SessionPermission::VerifySessionPermission()) {
6258 WLOGFE("The caller has not permission granted");
6259 return WSError::WS_ERROR_INVALID_PERMISSION;
6260 }
6261 auto task = [this, &deviceId, persistentId, &sessionInfo]() {
6262 if (CheckIsRemote(deviceId)) {
6263 int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
6264 if (ret != ERR_OK) {
6265 return WSError::WS_ERROR_INVALID_PARAM;
6266 } else {
6267 return WSError::WS_OK;
6268 }
6269 }
6270 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6271 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6272 iter = sceneSessionMap_.find(persistentId);
6273 if (iter != sceneSessionMap_.end()) {
6274 auto sceneSession = iter->second;
6275 if (sceneSession == nullptr) {
6276 WLOGFE("session: %{public}d is nullptr", persistentId);
6277 return WSError::WS_ERROR_INVALID_PARAM;
6278 }
6279 auto sceneSessionInfo = sceneSession->GetSessionInfo();
6280 if (sceneSessionInfo.isSystem_) {
6281 WLOGFD("sessionId: %{public}d isSystemScene", persistentId);
6282 return WSError::WS_ERROR_INVALID_PARAM;
6283 }
6284 auto want = sceneSessionInfo.want;
6285 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
6286 want->GetElement().GetBundleName().empty()) {
6287 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6288 persistentId);
6289 return WSError::WS_ERROR_INTERNAL_ERROR;
6290 }
6291 WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
6292 sceneSessionInfo.bundleName_.c_str());
6293 return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
6294 } else {
6295 WLOGFW("sessionId: %{public}d not found", persistentId);
6296 return WSError::WS_ERROR_INVALID_PARAM;
6297 }
6298 };
6299 return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
6300 }
6301
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)6302 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
6303 SessionInfoBean& sessionInfo)
6304 {
6305 TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
6306 continueSessionId.c_str());
6307 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6308 TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
6309 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6310 }
6311 if (!SessionPermission::VerifySessionPermission()) {
6312 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
6313 return WSError::WS_ERROR_INVALID_PERMISSION;
6314 }
6315 auto task = [this, continueSessionId, &sessionInfo]() {
6316 WSError ret = WSError::WS_ERROR_INVALID_SESSION;
6317 {
6318 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6319 for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
6320 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
6321 ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
6322 break;
6323 }
6324 }
6325 }
6326
6327 TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
6328 // app continue report for distributed scheduled service
6329 SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
6330 static_cast<int32_t>(ret));
6331 return ret;
6332 };
6333 return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
6334 }
6335
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6336 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
6337 int32_t persistentId, SessionInfoBean& sessionInfo)
6338 {
6339 WLOGFI("GetRemoteSessionInfoFromDms begin");
6340 std::vector<SessionInfoBean> sessionVector;
6341 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
6342 if (result != ERR_OK) {
6343 return result;
6344 }
6345 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
6346 if (iter->id == persistentId) {
6347 sessionInfo = *iter;
6348 return ERR_OK;
6349 }
6350 }
6351 WLOGFW("missionId not found");
6352 return ERR_INVALID_VALUE;
6353 }
6354
CheckIsRemote(const std::string & deviceId)6355 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
6356 {
6357 if (deviceId.empty()) {
6358 WLOGFI("CheckIsRemote: deviceId is empty.");
6359 return false;
6360 }
6361 std::string localDeviceId;
6362 if (!GetLocalDeviceId(localDeviceId)) {
6363 WLOGFE("CheckIsRemote: get local deviceId failed");
6364 return false;
6365 }
6366 if (localDeviceId == deviceId) {
6367 WLOGFI("CheckIsRemote: deviceId is local.");
6368 return false;
6369 }
6370 WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
6371 return true;
6372 }
6373
GetLocalDeviceId(std::string & localDeviceId)6374 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
6375 {
6376 auto localNode = std::make_unique<NodeBasicInfo>();
6377 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
6378 if (errCode != ERR_OK) {
6379 WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
6380 return false;
6381 }
6382 if (localNode != nullptr) {
6383 localDeviceId = localNode->networkId;
6384 WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
6385 return true;
6386 }
6387 WLOGFE("localDeviceId null");
6388 return false;
6389 }
6390
AnonymizeDeviceId(const std::string & deviceId)6391 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
6392 {
6393 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
6394 return EMPTY_DEVICE_ID;
6395 }
6396 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
6397 anonDeviceId.append("******");
6398 return anonDeviceId;
6399 }
6400
DumpSessionAll(std::vector<std::string> & infos)6401 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
6402 {
6403 WLOGFI("Dump all session.");
6404 if (!SessionPermission::IsSystemCalling()) {
6405 WLOGFE("DumpSessionAll permission denied!");
6406 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6407 }
6408
6409 auto task = [this, &infos]() {
6410 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6411 infos.push_back(dumpInfo);
6412 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6413 for (const auto &item : sceneSessionMap_) {
6414 auto& session = item.second;
6415 if (session) {
6416 session->DumpSessionInfo(infos);
6417 }
6418 }
6419 return WSError::WS_OK;
6420 };
6421
6422 return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
6423 }
6424
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)6425 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
6426 {
6427 WLOGFI("Dump session with id %{public}d", persistentId);
6428 if (!SessionPermission::IsSystemCalling()) {
6429 WLOGFE("DumpSessionWithId permission denied!");
6430 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6431 }
6432
6433 auto task = [this, persistentId, &infos]() {
6434 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6435 infos.push_back(dumpInfo);
6436 auto session = GetSceneSession(persistentId);
6437 if (session) {
6438 session->DumpSessionInfo(infos);
6439 } else {
6440 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
6441 }
6442 return WSError::WS_OK;
6443 };
6444
6445 return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
6446 }
6447
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6448 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
6449 const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6450 {
6451 if (bundleMgr_ == nullptr) {
6452 WLOGFE("bundleMgr_ is nullptr");
6453 return WSError::WS_ERROR_NULLPTR;
6454 }
6455 auto elementName = want.GetElement();
6456 int32_t ret{0};
6457 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6458 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6459 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6460 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6461 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6462 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6463 std::vector<AppExecFwk::BundleInfo> bundleInfos;
6464 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
6465 WLOGFD("want is empty queryAllAbilityInfos");
6466 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
6467 if (ret) {
6468 WLOGFE("Query all ability infos from BMS failed!");
6469 return WSError::WS_ERROR_INVALID_PARAM;
6470 }
6471 } else if (!elementName.GetBundleName().empty()) {
6472 AppExecFwk::BundleInfo bundleInfo;
6473 WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
6474 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
6475 if (ret) {
6476 WLOGFE("Query ability info from BMS failed!");
6477 return WSError::WS_ERROR_INVALID_PARAM;
6478 }
6479 bundleInfos.push_back(bundleInfo);
6480 } else {
6481 WLOGFE("invalid want:%{public}s", want.ToString().c_str());
6482 return WSError::WS_ERROR_INVALID_PARAM;
6483 }
6484 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6485 }
6486
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6487 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
6488 const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6489 {
6490 if (bundleMgr_ == nullptr) {
6491 TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
6492 return WSError::WS_ERROR_NULLPTR;
6493 }
6494 if (bundleNames.empty()) {
6495 TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
6496 return WSError::WS_ERROR_INVALID_PARAM;
6497 }
6498 auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6499 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6500 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6501 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6502 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6503 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
6504 std::vector<AppExecFwk::BundleInfo> bundleInfos;
6505 auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
6506 if (ret) {
6507 TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
6508 return WSError::WS_ERROR_INVALID_PARAM;
6509 }
6510 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6511 }
6512
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)6513 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
6514 const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
6515 {
6516 if (bundleMgr_ == nullptr) {
6517 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
6518 return WSError::WS_ERROR_NULLPTR;
6519 }
6520 auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6521 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6522 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6523 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6524 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6525 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6526 AppExecFwk::BundleInfo bundleInfo;
6527 if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
6528 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
6529 return WSError::WS_ERROR_INVALID_PARAM;
6530 }
6531 auto& hapModulesList = bundleInfo.hapModuleInfos;
6532 if (hapModulesList.empty()) {
6533 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
6534 return WSError::WS_ERROR_INVALID_PARAM;
6535 }
6536 auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
6537 for (auto& hapModule : hapModulesList) {
6538 auto& abilityInfoList = hapModule.abilityInfos;
6539 for (auto& abilityInfo : abilityInfoList) {
6540 if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
6541 scbAbilityInfo.abilityInfo_ = abilityInfo;
6542 scbAbilityInfo.sdkVersion_ = sdkVersion;
6543 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6544 return WSError::WS_OK;
6545 }
6546 }
6547 }
6548 TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
6549 return WSError::WS_ERROR_INVALID_PARAM;
6550 }
6551
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)6552 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
6553 std::vector<SCBAbilityInfo>& scbAbilityInfos)
6554 {
6555 if (bundleInfos.empty()) {
6556 WLOGFE("bundleInfos is empty");
6557 return WSError::WS_ERROR_INVALID_PARAM;
6558 }
6559 for (auto& bundleInfo : bundleInfos) {
6560 auto& hapModulesList = bundleInfo.hapModuleInfos;
6561 auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
6562 if (hapModulesList.empty()) {
6563 WLOGFD("hapModulesList is empty");
6564 continue;
6565 }
6566 if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
6567 bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
6568 auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
6569 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
6570 if (iter != hapModulesList.end()) {
6571 SCBAbilityInfo scbAbilityInfo;
6572 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
6573 scbAbilityInfo.sdkVersion_ = sdkVersion;
6574 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6575 scbAbilityInfos.push_back(scbAbilityInfo);
6576 continue;
6577 }
6578 }
6579 for (auto& hapModule : hapModulesList) {
6580 auto& abilityInfoList = hapModule.abilityInfos;
6581 for (auto& abilityInfo : abilityInfoList) {
6582 SCBAbilityInfo scbAbilityInfo;
6583 scbAbilityInfo.abilityInfo_ = abilityInfo;
6584 scbAbilityInfo.sdkVersion_ = sdkVersion;
6585 scbAbilityInfos.push_back(scbAbilityInfo);
6586 }
6587 }
6588 }
6589 return WSError::WS_OK;
6590 }
6591
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)6592 WSError SceneSessionManager::TerminateSessionNew(
6593 const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
6594 {
6595 if (info == nullptr) {
6596 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
6597 return WSError::WS_ERROR_INVALID_PARAM;
6598 }
6599 TLOGI(WmsLogTag::WMS_LIFE,
6600 "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
6601 info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
6602 int32_t callingPid = IPCSkeleton::GetCallingPid();
6603 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
6604 auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
6605 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
6606 if (sceneSession == nullptr) {
6607 TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
6608 return WSError::WS_ERROR_INVALID_PARAM;
6609 }
6610 const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
6611 if (!pidCheck &&
6612 !SessionPermission::VerifyPermissionByCallerToken(callerToken,
6613 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6614 TLOGE(WmsLogTag::WMS_LIFE,
6615 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
6616 sceneSession->GetCallingPid(), callingPid);
6617 return WSError::WS_ERROR_INVALID_PERMISSION;
6618 }
6619 WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
6620 return errCode;
6621 };
6622 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
6623 }
6624
SetVmaCacheStatus(bool flag)6625 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
6626 {
6627 WLOGFI("flag: %{public}d", flag);
6628 RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
6629 return WSError::WS_OK;
6630 }
6631
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)6632 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
6633 SessionSnapshot& snapshot, bool isLowResolution)
6634 {
6635 WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
6636 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6637 WLOGFE("The caller is not system-app, can not use system-api");
6638 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6639 }
6640 if (!SessionPermission::VerifySessionPermission()) {
6641 WLOGFE("The caller has not permission granted");
6642 return WSError::WS_ERROR_INVALID_PERMISSION;
6643 }
6644 auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
6645 if (CheckIsRemote(deviceId)) {
6646 int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
6647 if (ret != ERR_OK) {
6648 return WSError::WS_ERROR_INVALID_PARAM;
6649 } else {
6650 return WSError::WS_OK;
6651 }
6652 }
6653 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6654 if (!sceneSession) {
6655 return WSError::WS_ERROR_INVALID_PARAM;
6656 }
6657 auto sessionInfo = sceneSession->GetSessionInfo();
6658 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6659 WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6660 sceneSession->GetPersistentId());
6661 }
6662 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
6663 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
6664 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
6665 auto oriSnapshot = sceneSession->Snapshot();
6666 if (oriSnapshot != nullptr) {
6667 if (isLowResolution) {
6668 OHOS::Media::InitializationOptions options;
6669 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
6670 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
6671 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap
6672 = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
6673 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
6674 } else {
6675 snapshot.snapshot = oriSnapshot;
6676 }
6677 }
6678 return WSError::WS_OK;
6679 };
6680 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
6681 }
6682
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)6683 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
6684 {
6685 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
6686 TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
6687 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6688 }
6689 auto task = [this, persistentId, &snapshot]() {
6690 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6691 if (!sceneSession) {
6692 TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
6693 return WMError::WM_ERROR_INVALID_PARAM;
6694 }
6695 auto sessionInfo = sceneSession->GetSessionInfo();
6696 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6697 TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6698 sceneSession->GetPersistentId());
6699 }
6700 snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
6701 snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
6702 snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
6703 auto oriSnapshot = sceneSession->Snapshot();
6704 if (oriSnapshot != nullptr) {
6705 snapshot.snapshot = oriSnapshot;
6706 return WMError::WM_OK;
6707 }
6708 return WMError::WM_ERROR_NULLPTR;
6709 };
6710 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
6711 }
6712
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)6713 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
6714 {
6715 if (!SessionPermission::IsSACalling()) {
6716 TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
6717 return WSError::WS_ERROR_INVALID_PERMISSION;
6718 }
6719 TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
6720 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6721 if (sceneSession == nullptr) {
6722 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
6723 return WSError::WS_ERROR_NULLPTR;
6724 }
6725 return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
6726 }
6727
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)6728 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
6729 AAFwk::MissionSnapshot& sessionSnapshot)
6730 {
6731 TLOGI(WmsLogTag::DEFAULT, "begin");
6732 int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
6733 sessionId, sessionSnapshot);
6734 if (result != ERR_OK) {
6735 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6736 return result;
6737 }
6738 return ERR_OK;
6739 }
6740
GetCollaboratorByType(int32_t collaboratorType)6741 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
6742 {
6743 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
6744 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
6745 auto iter = collaboratorMap_.find(collaboratorType);
6746 if (iter == collaboratorMap_.end()) {
6747 TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
6748 return collaborator;
6749 }
6750 collaborator = iter->second;
6751 if (collaborator == nullptr) {
6752 TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
6753 }
6754 return collaborator;
6755 }
6756
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)6757 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
6758 {
6759 wptr<SceneSession> weakSceneSession(sceneSession);
6760 auto task = [this, weakSceneSession]() {
6761 auto scnSession = weakSceneSession.promote();
6762 if (scnSession == nullptr) {
6763 WLOGFE("session is nullptr");
6764 return WSError::WS_ERROR_NULLPTR;
6765 }
6766 auto persistentId = scnSession->GetPersistentId();
6767 if (!GetSceneSession(persistentId)) {
6768 WLOGFE("session is invalid with %{public}d", persistentId);
6769 return WSError::WS_ERROR_INVALID_SESSION;
6770 }
6771 auto sessionInfo = scnSession->GetSessionInfo();
6772 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
6773 if (!abilitySessionInfo) {
6774 TLOGE(WmsLogTag::WMS_MAIN,
6775 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
6776 return WSError::WS_ERROR_NULLPTR;
6777 }
6778 TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
6779 sessionInfo.callState_, persistentId);
6780 bool isColdStart = false;
6781 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
6782 if (isColdStart) {
6783 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
6784 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
6785 scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
6786 scnSession->ResetSessionConnectState();
6787 }
6788 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
6789 return WSError::WS_OK;
6790 };
6791 std::string taskName = "RequestSceneSessionByCall:PID:" +
6792 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
6793 taskScheduler_->PostAsyncTask(task, taskName);
6794 return WSError::WS_OK;
6795 }
6796
StartAbilityBySpecified(const SessionInfo & sessionInfo)6797 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
6798 {
6799 auto task = [this, sessionInfo]() {
6800 WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
6801 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6802 AAFwk::Want want;
6803 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
6804 if (sessionInfo.want != nullptr) {
6805 want.SetParams(sessionInfo.want->GetParams());
6806 }
6807 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
6808 };
6809
6810 taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
6811 }
6812
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)6813 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
6814 {
6815 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
6816 if (pid == -1) {
6817 TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
6818 return;
6819 }
6820 int32_t ret = HiSysEventWrite(
6821 HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
6822 "WINDOW_STATE_ERROR",
6823 HiviewDFX::HiSysEvent::EventType::FAULT,
6824 "PID", pid,
6825 "PERSISTENT_ID", persistentId);
6826 if (ret != 0) {
6827 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
6828 }
6829 auto task = [this, pid] {
6830 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6831 for (const auto& [_, sceneSession] : sceneSessionMap_) {
6832 if (!sceneSession || pid != sceneSession->GetCallingPid() ||
6833 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6834 continue;
6835 }
6836 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6837 if (abilitySessionInfo) {
6838 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
6839 abilitySessionInfo->persistentId);
6840 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
6841 }
6842 }
6843 };
6844 // delay 2000ms, wait for hidumper
6845 taskScheduler_->PostAsyncTask(task, __func__, 2000);
6846 }
6847
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)6848 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
6849 {
6850 if (!targetToken) {
6851 WLOGFE("Token is null, cannot find main window");
6852 return nullptr;
6853 }
6854
6855 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6856 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
6857 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
6858 if (pair.second->IsTerminated()) {
6859 return false;
6860 }
6861 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6862 return pair.second->GetAbilityToken() == targetToken;
6863 }
6864 return false;
6865 });
6866 if (iter == sceneSessionMap_.end()) {
6867 WLOGFE("Cannot find session");
6868 return nullptr;
6869 }
6870 return iter->second;
6871 }
6872
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)6873 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
6874 {
6875 if (!SessionPermission::IsSystemCalling()) {
6876 TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
6877 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6878 }
6879 if (targetToken == nullptr) {
6880 TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
6881 return WSError::WS_ERROR_NULLPTR;
6882 }
6883
6884 auto task = [this, persistentId, targetToken]() {
6885 auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
6886 if (scnSession == nullptr) {
6887 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
6888 return WSError::WS_ERROR_NULLPTR;
6889 }
6890 if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
6891 TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
6892 return WSError::WS_OK;
6893 }
6894 scnSession->dialogTargetToken_ = targetToken;
6895 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
6896 if (parentSession == nullptr) {
6897 scnSession->NotifyDestroy();
6898 return WSError::WS_ERROR_INVALID_PARAM;
6899 }
6900 scnSession->SetParentSession(parentSession);
6901 scnSession->SetParentPersistentId(parentSession->GetPersistentId());
6902 UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
6903 TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
6904 persistentId, parentSession->GetPersistentId());
6905 return WSError::WS_OK;
6906 };
6907 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
6908 }
6909
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)6910 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
6911 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
6912 {
6913 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
6914 }
6915
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)6916 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
6917 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
6918 {
6919 auto isSaCall = SessionPermission::IsSACalling();
6920 if (!isSaCall) {
6921 WLOGFE("The interface only support for sa call");
6922 return WMError::WM_ERROR_INVALID_PERMISSION;
6923 }
6924 auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
6925 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6926 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6927 for (auto missionId : missionIds) {
6928 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
6929 if (iter == sceneSessionMap_.end()) {
6930 continue;
6931 }
6932 auto sceneSession = iter->second;
6933 if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
6934 continue;
6935 }
6936 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
6937 if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
6938 surfaceNodeIds.push_back(missionId);
6939 continue;
6940 }
6941 if (sceneSession->GetLeashWinSurfaceNode()) {
6942 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
6943 }
6944 }
6945 return WMError::WM_OK;
6946 };
6947 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
6948 }
6949
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)6950 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
6951 const sptr<IWindowManagerAgent>& windowManagerAgent)
6952 {
6953 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
6954 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
6955 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
6956 if (!SessionPermission::IsSystemCalling()) {
6957 WLOGFE("RegisterWindowManagerAgent permission denied!");
6958 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6959 }
6960 } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
6961 if (!SessionPermission::IsSystemServiceCalling()) {
6962 return WMError::WM_ERROR_INVALID_PERMISSION;
6963 }
6964 }
6965 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
6966 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
6967 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
6968 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
6969 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
6970 if (!SessionPermission::IsSACalling()) {
6971 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
6972 return WMError::WM_ERROR_INVALID_PERMISSION;
6973 }
6974 }
6975 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
6976 WLOGFE("windowManagerAgent is null");
6977 return WMError::WM_ERROR_NULLPTR;
6978 }
6979 const auto callingPid = IPCSkeleton::GetCallingRealPid();
6980 auto task = [this, windowManagerAgent, type, callingPid]() {
6981 return SessionManagerAgentController::GetInstance()
6982 .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
6983 };
6984 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
6985 }
6986
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)6987 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
6988 const sptr<IWindowManagerAgent>& windowManagerAgent)
6989 {
6990 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
6991 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
6992 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
6993 if (!SessionPermission::IsSystemCalling()) {
6994 WLOGFE("UnregisterWindowManagerAgent permission denied!");
6995 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6996 }
6997 }
6998 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
6999 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7000 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7001 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7002 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7003 if (!SessionPermission::IsSACalling()) {
7004 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7005 return WMError::WM_ERROR_INVALID_PERMISSION;
7006 }
7007 }
7008 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7009 WLOGFE("windowManagerAgent is null");
7010 return WMError::WM_ERROR_NULLPTR;
7011 }
7012 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7013 auto task = [this, windowManagerAgent, type, callingPid]() {
7014 return SessionManagerAgentController::GetInstance()
7015 .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7016 };
7017 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7018 }
7019
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)7020 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7021 {
7022 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7023 }
7024
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)7025 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7026 {
7027 SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7028 }
7029
StartWindowInfoReportLoop()7030 void SceneSessionManager::StartWindowInfoReportLoop()
7031 {
7032 WLOGFD("Report loop");
7033 if (eventHandler_ == nullptr) {
7034 WLOGFE("Report event null");
7035 return ;
7036 }
7037 if (isReportTaskStart_) {
7038 WLOGFE("Report is ReportTask Start");
7039 return;
7040 }
7041 auto task = [this]() {
7042 WindowInfoReporter::GetInstance().ReportRecordedInfos();
7043 ReportWindowProfileInfos();
7044 isReportTaskStart_ = false;
7045 StartWindowInfoReportLoop();
7046 };
7047 int64_t delayTime = 1000 * 60 * 60; // an hour.
7048 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7049 if (!ret) {
7050 WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
7051 return;
7052 }
7053 isReportTaskStart_ = true;
7054 }
7055
InitPersistentStorage()7056 void SceneSessionManager::InitPersistentStorage()
7057 {
7058 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7059 int32_t storageMode = -1;
7060 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7061 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7062 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7063 WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7064 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7065 }
7066 }
7067 }
7068
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)7069 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7070 {
7071 WLOGFD("Called.");
7072 if (!SessionPermission::IsSystemServiceCalling()) {
7073 WLOGFE("Only support for system service.");
7074 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7075 }
7076 auto task = [this, &infos]() {
7077 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7078 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7079 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7080 sptr<SceneSession> sceneSession = iter->second;
7081 if (sceneSession == nullptr) {
7082 WLOGFW("null scene session");
7083 continue;
7084 }
7085 bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7086 sceneSession->IsVisibleForAccessibility() :
7087 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7088 WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7089 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7090 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7091 sceneSession->GetSessionState(), isVisibleForAccessibility);
7092 if (isVisibleForAccessibility) {
7093 FillWindowInfo(infos, iter->second);
7094 }
7095 }
7096 return WMError::WM_OK;
7097 };
7098 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7099 }
7100
CheckUnreliableWindowType(WindowType windowType)7101 static bool CheckUnreliableWindowType(WindowType windowType)
7102 {
7103 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7104 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7105 windowType == WindowType::WINDOW_TYPE_TOAST) {
7106 return true;
7107 }
7108 TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7109 return false;
7110 }
7111
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)7112 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7113 std::vector<sptr<UnreliableWindowInfo>>& infos)
7114 {
7115 if (sceneSession == nullptr) {
7116 TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7117 return;
7118 }
7119 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7120 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7121 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7122 TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7123 return;
7124 }
7125 sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo();
7126 if (info == nullptr) {
7127 TLOGE(WmsLogTag::DEFAULT, "null info.");
7128 return;
7129 }
7130 info->windowId_ = sceneSession->GetPersistentId();
7131 WSRect windowRect = sceneSession->GetSessionRect();
7132 info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7133 info->zOrder_ = sceneSession->GetZOrder();
7134 info->floatingScale_ = sceneSession->GetFloatingScale();
7135 info->scaleX_ = sceneSession->GetScaleX();
7136 info->scaleY_ = sceneSession->GetScaleY();
7137 infos.emplace_back(info);
7138 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7139 }
7140
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)7141 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
7142 std::vector<sptr<UnreliableWindowInfo>>& infos)
7143 {
7144 TLOGD(WmsLogTag::DEFAULT, "Called.");
7145 if (!SessionPermission::IsSystemServiceCalling()) {
7146 TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
7147 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7148 }
7149 auto task = [this, windowId, &infos]() {
7150 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7151 for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
7152 if (sceneSession == nullptr) {
7153 TLOGW(WmsLogTag::DEFAULT, "null scene session");
7154 continue;
7155 }
7156 if (sessionId == windowId) {
7157 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
7158 FillUnreliableWindowInfo(sceneSession, infos);
7159 continue;
7160 }
7161 if (!sceneSession->GetRSVisible()) {
7162 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
7163 continue;
7164 }
7165 TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
7166 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
7167 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
7168 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
7169 if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
7170 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
7171 "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
7172 FillUnreliableWindowInfo(sceneSession, infos);
7173 }
7174 }
7175 return WMError::WM_OK;
7176 };
7177 return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
7178 }
7179
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)7180 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
7181 {
7182 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
7183 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7184 if (sceneSession == nullptr) {
7185 WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
7186 return;
7187 }
7188 wptr<SceneSession> weakSceneSession(sceneSession);
7189 if (processingFlushUIParams_.load()) {
7190 TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
7191 auto task = [this, weakSceneSession, type]() {
7192 auto sceneSession = weakSceneSession.promote();
7193 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7194 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7195 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7196 }
7197 };
7198 taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
7199 return;
7200 }
7201 auto task = [this, weakSceneSession, type]() {
7202 auto sceneSession = weakSceneSession.promote();
7203 NotifyAllAccessibilityInfo();
7204 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7205 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7206 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7207 }
7208 };
7209 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:id:" + std::to_string(persistentId));
7210
7211 auto notifySceneInputTask = [weakSceneSession, type]() {
7212 auto sceneSession = weakSceneSession.promote();
7213 if (sceneSession == nullptr) {
7214 return;
7215 }
7216 SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
7217 };
7218 taskScheduler_->PostAsyncTask(notifySceneInputTask);
7219 }
7220
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)7221 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
7222 const sptr<SceneSession>& sceneSession)
7223 {
7224 if (sceneSession == nullptr) {
7225 WLOGFW("null scene session.");
7226 return false;
7227 }
7228 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7229 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7230 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7231 WLOGFD("filter gesture window.");
7232 return false;
7233 }
7234 sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
7235 if (info == nullptr) {
7236 WLOGFE("null info.");
7237 return false;
7238 }
7239 if (sceneSession->GetSessionInfo().isSystem_) {
7240 info->wid_ = 1;
7241 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7242 } else {
7243 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7244 }
7245 info->uiNodeId_ = sceneSession->GetUINodeId();
7246 WSRect wsrect = sceneSession->GetSessionGlobalRect(); // only accessability and mmi need global
7247 info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
7248 info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
7249 info->type_ = sceneSession->GetWindowType();
7250 info->mode_ = sceneSession->GetWindowMode();
7251 info->layer_ = sceneSession->GetZOrder();
7252 info->scaleVal_ = sceneSession->GetFloatingScale();
7253 info->scaleX_ = sceneSession->GetScaleX();
7254 info->scaleY_ = sceneSession->GetScaleY();
7255 info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
7256 info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
7257 auto property = sceneSession->GetSessionProperty();
7258 if (property != nullptr) {
7259 info->displayId_ = property->GetDisplayId();
7260 info->isDecorEnable_ = property->IsDecorEnable();
7261 }
7262 infos.emplace_back(info);
7263 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
7264 info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
7265 return true;
7266 }
7267
GetSessionSnapshotFilePath(int32_t persistentId)7268 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
7269 {
7270 WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
7271 auto sceneSession = GetSceneSession(persistentId);
7272 if (sceneSession == nullptr) {
7273 WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
7274 return "";
7275 }
7276 wptr<SceneSession> weakSceneSession(sceneSession);
7277 auto task = [this, weakSceneSession]() {
7278 auto scnSession = weakSceneSession.promote();
7279 if (scnSession == nullptr) {
7280 WLOGFE("session is nullptr");
7281 return std::string("");
7282 }
7283 std::string filePath = scnSession->GetSessionSnapshotFilePath();
7284 return filePath;
7285 };
7286 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
7287 }
7288
SelectSesssionFromMap(const uint64_t & surfaceId)7289 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
7290 {
7291 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7292 for (const auto &item : sceneSessionMap_) {
7293 auto sceneSession = item.second;
7294 if (sceneSession == nullptr) {
7295 continue;
7296 }
7297 if (sceneSession->GetSurfaceNode() == nullptr) {
7298 continue;
7299 }
7300 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
7301 return sceneSession;
7302 }
7303 }
7304 return nullptr;
7305 }
7306
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)7307 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
7308 {
7309 WLOGFD("WindowLayerInfoChangeCallback: entry");
7310 std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
7311
7312 auto task = [this, weak]() {
7313 auto weakOcclusionData = weak.lock();
7314 if (weakOcclusionData == nullptr) {
7315 WLOGFE("weak occlusionData is nullptr");
7316 return;
7317 }
7318 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
7319 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
7320 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
7321 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
7322 if (currVisibleData.size() != 0) {
7323 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
7324 }
7325 if (visibilityChangeInfos.size() != 0) {
7326 DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
7327 CacVisibleWindowNum();
7328 }
7329
7330 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
7331 if (currDrawingContentData.size() != 0) {
7332 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
7333 }
7334 if (drawingContentChangeInfos.size() != 0) {
7335 DealwithDrawingContentChange(drawingContentChangeInfos);
7336 }
7337 };
7338 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
7339 }
7340
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)7341 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
7342 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
7343 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
7344 {
7345 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
7346 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
7347 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
7348 switch (windowLayerState) {
7349 case WINDOW_ALL_VISIBLE:
7350 case WINDOW_SEMI_VISIBLE:
7351 case WINDOW_IN_VISIBLE:
7352 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
7353 break;
7354 case WINDOW_LAYER_DRAWING:
7355 currDrawingContentData.emplace_back(iter->first, true);
7356 break;
7357 case WINDOW_LAYER_NO_DRAWING:
7358 currDrawingContentData.emplace_back(iter->first, false);
7359 break;
7360 default:
7361 break;
7362 }
7363 }
7364 }
7365
UpdateSubWindowVisibility(const sptr<SceneSession> & session,WindowVisibilityState visibleState,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7366 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
7367 WindowVisibilityState visibleState,
7368 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7369 std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
7370 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7371 {
7372 if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
7373 visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7374 auto subSessions = GetSubSceneSession(session->GetWindowId());
7375 if (subSessions.empty()) {
7376 return;
7377 }
7378
7379 RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
7380
7381 for (const auto& subSession : subSessions) {
7382 if (subSession == nullptr) {
7383 continue;
7384 }
7385 if (session->GetCallingPid() != subSession->GetCallingPid() &&
7386 (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData))) {
7387 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
7388 subSession->GetWindowId());
7389 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
7390 }
7391 }
7392 }
7393 }
7394
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7395 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
7396 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7397 {
7398 bool sessionRSVisible = false;
7399 for (const auto& elem : currVisibleData) {
7400 uint64_t surfaceId = elem.first;
7401 WindowVisibilityState visibleState = elem.second;
7402 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7403 sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
7404 if (visibilitySession == nullptr) {
7405 continue;
7406 }
7407 if (session->GetWindowId() == visibilitySession->GetWindowId()) {
7408 if (isVisible) {
7409 sessionRSVisible = true;
7410 }
7411 break;
7412 }
7413 }
7414 return sessionRSVisible;
7415 }
7416
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)7417 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
7418 WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
7419 std::string& visibilityInfo)
7420 {
7421 if (session == nullptr) {
7422 TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
7423 return;
7424 }
7425 session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7426 session->SetVisibilityState(visibleState);
7427 int32_t windowId = session->GetWindowId();
7428 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
7429 session->NotifyWindowVisibility();
7430 }
7431 windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
7432 windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
7433
7434 visibilityInfo +=
7435 "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
7436 }
7437
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)7438 void SceneSessionManager::RemoveDuplicateSubSession(
7439 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7440 std::vector<sptr<SceneSession>>& subSessions)
7441 {
7442 for (const auto& elem : visibilityChangeInfo) {
7443 uint64_t surfaceId = elem.first;
7444 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7445 if (session == nullptr) {
7446 continue;
7447 }
7448 for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
7449 auto subSession = *iterator;
7450 if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
7451 iterator = subSessions.erase(iterator);
7452 } else {
7453 ++iterator;
7454 }
7455 }
7456 }
7457 }
7458
GetSubSceneSession(int32_t parentWindowId)7459 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
7460 {
7461 std::vector<sptr<SceneSession>> subSessions;
7462 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7463 for (const auto& iter : sceneSessionMap_) {
7464 auto sceneSession = iter.second;
7465 if (sceneSession == nullptr) {
7466 continue;
7467 }
7468 if (sceneSession->GetParentSession() != nullptr &&
7469 sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
7470 subSessions.push_back(sceneSession);
7471 }
7472 }
7473 return subSessions;
7474 }
7475
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7476 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
7477 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7478 {
7479 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
7480 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
7481 uint32_t i, j;
7482 i = j = 0;
7483 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
7484 if (lastVisibleData_[i].first < currVisibleData[j].first) {
7485 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7486 i++;
7487 } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
7488 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7489 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7490 }
7491 j++;
7492 } else {
7493 if (lastVisibleData_[i].second != currVisibleData[j].second) {
7494 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7495 }
7496 i++;
7497 j++;
7498 }
7499 }
7500 for (; i < lastVisibleData_.size(); ++i) {
7501 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7502 }
7503 for (; j < currVisibleData.size(); ++j) {
7504 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7505 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7506 }
7507 }
7508 lastVisibleData_ = currVisibleData;
7509 return visibilityChangeInfo;
7510 }
7511
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7512 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
7513 visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7514 {
7515 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7516 #ifdef MEMMGR_WINDOW_ENABLE
7517 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7518 #endif
7519
7520 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
7521 for (const auto& elem : visibilityChangeInfo) {
7522 uint64_t surfaceId = elem.first;
7523 WindowVisibilityState visibleState = elem.second;
7524 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7525 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7526 if (session == nullptr) {
7527 continue;
7528 }
7529 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
7530 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
7531 if (session->GetParentSession() != nullptr &&
7532 !session->GetParentSession()->IsSessionForeground() &&
7533 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
7534 continue;
7535 }
7536 }
7537 SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
7538 UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
7539 #ifdef MEMMGR_WINDOW_ENABLE
7540 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
7541 session->GetCallingUid(), isVisible));
7542 #endif
7543 CheckAndNotifyWaterMarkChangedResult();
7544 }
7545 if (windowVisibilityInfos.size() != 0) {
7546 WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
7547 visibilityInfo.c_str());
7548 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7549 }
7550 #ifdef MEMMGR_WINDOW_ENABLE
7551 if (memMgrWindowInfos.size() != 0) {
7552 WLOGD("Notify memMgrWindowInfos changed start");
7553 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7554 }
7555 #endif
7556 }
7557
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)7558 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
7559 drawingContentChangeInfo)
7560 {
7561 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
7562 for (const auto& elem : drawingContentChangeInfo) {
7563 uint64_t surfaceId = elem.first;
7564 bool drawingState = elem.second;
7565 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7566 if (session == nullptr) {
7567 continue;
7568 }
7569 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
7570 session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
7571 if (openDebugTrace) {
7572 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
7573 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
7574 }
7575 WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
7576 "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
7577 }
7578 if (windowDrawingContenInfos.size() != 0) {
7579 WLOGFD("Notify WindowDrawingContenInfo changed start");
7580 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
7581 }
7582 }
7583
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)7584 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
7585 std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
7586 {
7587 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
7588 for (const auto& data : currDrawingContentData) {
7589 uint64_t windowId = data.first;
7590 bool currentDrawingContentState = data.second;
7591 int32_t pid = 0;
7592 bool isChange = false;
7593 if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
7594 continue;
7595 } else {
7596 isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
7597 }
7598 if (isChange) {
7599 processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
7600 }
7601 }
7602 return processDrawingContentChangeInfo;
7603 }
7604
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)7605 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
7606 {
7607 bool preWindowDrawingState = true;
7608 sptr<SceneSession> session = SelectSesssionFromMap(windowId);
7609 if (session == nullptr) {
7610 return false;
7611 }
7612 pid = session->GetCallingPid();
7613 preWindowDrawingState = session->GetDrawingContentState();
7614 session->SetDrawingContentState(currentDrawingContentState);
7615 return preWindowDrawingState;
7616 }
7617
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)7618 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
7619 {
7620 bool isChange = true;
7621 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7622 for (const auto& item : sceneSessionMap_) {
7623 auto sceneSession = item.second;
7624 if (sceneSession == nullptr) {
7625 continue;
7626 }
7627 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
7628 windowId != sceneSession->GetSurfaceNode()->GetId()) {
7629 if (sceneSession->GetDrawingContentState()) {
7630 return false;
7631 }
7632 }
7633 }
7634 return isChange;
7635 }
7636
InitWithRenderServiceAdded()7637 void SceneSessionManager::InitWithRenderServiceAdded()
7638 {
7639 auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
7640 this->WindowLayerInfoChangeCallback(occlusiontionData);
7641 };
7642 WLOGI("RegisterWindowVisibilityChangeCallback");
7643 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
7644 WLOGFE("RegisterWindowVisibilityChangeCallback failed");
7645 }
7646 }
7647
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)7648 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
7649 {
7650 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
7651 WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
7652 return WMError::WM_ERROR_INVALID_PARAM;
7653 }
7654
7655 auto task = [this, sceneType]() {
7656 WLOGFD("Set system animated scene %{public}d.", sceneType);
7657 bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
7658 if (!ret) {
7659 WLOGFE("Set system animated scene failed.");
7660 }
7661 };
7662 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
7663 return WMError::WM_OK;
7664 }
7665
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)7666 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
7667 {
7668 if (!SessionPermission::IsSystemCalling()) {
7669 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
7670 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7671 }
7672 if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
7673 TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
7674 return WSError::WS_ERROR_INVALID_PERMISSION;
7675 }
7676 TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
7677 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
7678 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7679 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
7680 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
7681 WindowType::WINDOW_TYPE_APP_COMPONENT));
7682 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7683 return WSError::WS_OK;
7684 }
7685
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)7686 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
7687 {
7688 if (sceneSession == nullptr) {
7689 WLOGFE("sceneSession is nullptr!");
7690 return;
7691 }
7692 if (sceneSession->GetRSVisible()) {
7693 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7694 #ifdef MEMMGR_WINDOW_ENABLE
7695 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7696 #endif
7697 sceneSession->SetRSVisible(false);
7698 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7699 sceneSession->ClearExtWindowFlags();
7700 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
7701 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
7702 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
7703 #ifdef MEMMGR_WINDOW_ENABLE
7704 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
7705 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
7706 #endif
7707 WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
7708 sceneSession->GetWindowId(), sceneSession->GetRSVisible());
7709 CheckAndNotifyWaterMarkChangedResult();
7710 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7711 #ifdef MEMMGR_WINDOW_ENABLE
7712 WLOGD("Notify memMgrWindowInfos changed start");
7713 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7714 #endif
7715 }
7716 }
7717
FindSessionByToken(const sptr<IRemoteObject> & token)7718 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
7719 {
7720 if (token == nullptr) {
7721 TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
7722 return nullptr;
7723 }
7724 sptr<SceneSession> session = nullptr;
7725 auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7726 if (pair.second == nullptr) {
7727 return false;
7728 }
7729 return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
7730 };
7731 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7732 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7733 if (iter != sceneSessionMap_.end()) {
7734 session = iter->second;
7735 }
7736 return session;
7737 }
7738
FindSessionByAffinity(std::string affinity)7739 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
7740 {
7741 if (affinity.size() == 0) {
7742 WLOGFI("AbilityInfo affinity is empty");
7743 return nullptr;
7744 }
7745 sptr<SceneSession> session = nullptr;
7746 auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7747 if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
7748 return false;
7749 }
7750 return pair.second->GetSessionInfo().sessionAffinity == affinity;
7751 };
7752 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7753 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7754 if (iter != sceneSessionMap_.end()) {
7755 session = iter->second;
7756 }
7757 return session;
7758 }
7759
PreloadInLakeApp(const std::string & bundleName)7760 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
7761 {
7762 WLOGFD("Enter name %{public}s", bundleName.c_str());
7763 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
7764 if (collaborator != nullptr) {
7765 WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
7766 collaborator->NotifyPreloadAbility(bundleName);
7767 }
7768 }
7769
PendingSessionToForeground(const sptr<IRemoteObject> & token)7770 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
7771 {
7772 TLOGI(WmsLogTag::DEFAULT, "Session is going to foreground");
7773 auto pid = IPCSkeleton::GetCallingRealPid();
7774 if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
7775 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
7776 return WSError::WS_ERROR_INVALID_PERMISSION;
7777 }
7778
7779 auto task = [this, &token]() {
7780 auto session = FindSessionByToken(token);
7781 if (session != nullptr) {
7782 return session->PendingSessionToForeground();
7783 }
7784 TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
7785 return WSError::WS_ERROR_INVALID_PARAM;
7786 };
7787 return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
7788 }
7789
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)7790 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
7791 bool shouldBackToCaller)
7792 {
7793 auto task = [this, &token, shouldBackToCaller] {
7794 auto session = FindSessionByToken(token);
7795 if (session != nullptr) {
7796 return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
7797 }
7798 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
7799 return WSError::WS_ERROR_INVALID_PARAM;
7800 };
7801 return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
7802 }
7803
ClearDisplayStatusBarTemporarilyFlags()7804 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
7805 {
7806 for (auto persistentId : avoidAreaListenerSessionSet_) {
7807 auto sceneSession = GetSceneSession(persistentId);
7808 if (sceneSession == nullptr) {
7809 continue;
7810 }
7811 sceneSession->SetIsDisplayStatusBarTemporarily(false);
7812 }
7813 }
7814
GetFocusSessionToken(sptr<IRemoteObject> & token)7815 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
7816 {
7817 if (!SessionPermission::IsSACalling()) {
7818 WLOGFE("GetFocusSessionToken permission denied!");
7819 return WSError::WS_ERROR_INVALID_PERMISSION;
7820 }
7821 auto task = [this, &token]() {
7822 WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
7823 auto sceneSession = GetSceneSession(focusedSessionId_);
7824 if (sceneSession) {
7825 token = sceneSession->GetAbilityToken();
7826 if (token == nullptr) {
7827 WLOGFE("token is nullptr");
7828 return WSError::WS_ERROR_INVALID_PARAM;
7829 }
7830 return WSError::WS_OK;
7831 }
7832 return WSError::WS_ERROR_INVALID_PARAM;
7833 };
7834 return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
7835 }
7836
GetFocusSessionElement(AppExecFwk::ElementName & element)7837 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
7838 {
7839 AppExecFwk::RunningProcessInfo info;
7840 auto pid = IPCSkeleton::GetCallingRealPid();
7841 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
7842 if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
7843 WLOGFE("GetFocusSessionElement permission denied!");
7844 return WSError::WS_ERROR_INVALID_PERMISSION;
7845 }
7846 auto task = [this, &element]() {
7847 WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
7848 auto sceneSession = GetSceneSession(focusedSessionId_);
7849 if (sceneSession) {
7850 auto sessionInfo = sceneSession->GetSessionInfo();
7851 element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
7852 sessionInfo.abilityName_, sessionInfo.moduleName_);
7853 return WSError::WS_OK;
7854 }
7855 return WSError::WS_ERROR_INVALID_SESSION;
7856 };
7857 return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
7858 }
7859
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)7860 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
7861 {
7862 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7863 auto task = [this, persistentId, haveListener, callingPid]() {
7864 TLOGI(WmsLogTag::WMS_IMMS,
7865 "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
7866 persistentId, haveListener);
7867 auto sceneSession = GetSceneSession(persistentId);
7868 if (sceneSession == nullptr) {
7869 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
7870 return WSError::WS_DO_NOTHING;
7871 }
7872 if (callingPid != sceneSession->GetCallingPid()) {
7873 TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
7874 return WSError::WS_ERROR_INVALID_PERMISSION;
7875 }
7876 if (haveListener) {
7877 avoidAreaListenerSessionSet_.insert(persistentId);
7878 UpdateAvoidArea(persistentId);
7879 } else {
7880 lastUpdatedAvoidArea_.erase(persistentId);
7881 avoidAreaListenerSessionSet_.erase(persistentId);
7882 }
7883 return WSError::WS_OK;
7884 };
7885 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
7886 }
7887
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const sptr<SceneSession> & sceneSession,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)7888 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
7889 const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
7890 {
7891 if (sceneSession == nullptr) {
7892 TLOGI(WmsLogTag::WMS_IMMS, "scene session null no need update avoid area");
7893 return false;
7894 }
7895 if (lastUpdatedAvoidArea_.find(persistentId) == lastUpdatedAvoidArea_.end()) {
7896 lastUpdatedAvoidArea_[persistentId] = {};
7897 }
7898
7899 bool needUpdate = true;
7900 if (auto iter = lastUpdatedAvoidArea_[persistentId].find(avoidAreaType);
7901 iter != lastUpdatedAvoidArea_[persistentId].end()) {
7902 needUpdate = iter->second != avoidArea;
7903 } else {
7904 if (avoidArea.isEmptyAvoidArea()) {
7905 TLOGI(WmsLogTag::WMS_IMMS, "window %{public}d type %{public}d empty avoid area",
7906 persistentId, avoidAreaType);
7907 needUpdate = false;
7908 return needUpdate;
7909 }
7910 }
7911 if (needUpdate) {
7912 lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
7913 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
7914 }
7915
7916 return needUpdate;
7917 }
7918
UpdateAvoidSessionAvoidArea(WindowType type,bool & needUpdate)7919 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
7920 {
7921 bool ret = true;
7922 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
7923 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
7924 for (auto& persistentId : avoidAreaListenerSessionSet_) {
7925 auto sceneSession = GetSceneSession(persistentId);
7926 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
7927 continue;
7928 }
7929 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
7930 ret = UpdateSessionAvoidAreaIfNeed(
7931 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
7932 needUpdate = needUpdate || ret;
7933 }
7934
7935 return;
7936 }
7937
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)7938 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
7939 {
7940 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
7941 !avoidArea.rightRect_.IsUninitializedRect()) {
7942 return false;
7943 }
7944 if (avoidArea.bottomRect_.IsUninitializedRect()) {
7945 return true;
7946 }
7947 if (isVisible &&
7948 (avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) == sessionBottom)) {
7949 return true;
7950 }
7951 return false;
7952 }
7953
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)7954 void SceneSessionManager::UpdateNormalSessionAvoidArea(
7955 const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
7956 {
7957 bool ret = true;
7958 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
7959 TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
7960 persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
7961 needUpdate = false;
7962 return;
7963 }
7964 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
7965 TLOGD(WmsLogTag::WMS_IMMS,
7966 "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
7967 needUpdate = false;
7968 return;
7969 }
7970 uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
7971 uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
7972 for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
7973 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
7974 if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
7975 !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
7976 sceneSession->GetSessionRect().height_)) {
7977 continue;
7978 }
7979 ret = UpdateSessionAvoidAreaIfNeed(
7980 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
7981 needUpdate = needUpdate || ret;
7982 }
7983
7984 return;
7985 }
7986
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)7987 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
7988 {
7989 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
7990 auto sceneSession = GetSceneSession(windowId);
7991 if (sceneSession == nullptr) {
7992 WLOGFW("window not exist: %{public}d", windowId);
7993 return;
7994 }
7995
7996 wptr<SceneSession> weakSceneSession(sceneSession);
7997 WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
7998 auto task = [weakSceneSession, startMoving]() -> WSError {
7999 auto scnSession = weakSceneSession.promote();
8000 if (scnSession == nullptr) {
8001 WLOGFW("session is null");
8002 return WSError::WS_ERROR_NULLPTR;
8003 }
8004 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8005 return WSError::WS_OK;
8006 };
8007 return taskScheduler_->PostAsyncTask(task);
8008 }
8009
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)8010 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
8011 const std::string taskName, const int delayTime)
8012 {
8013 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
8014 }
8015
UpdateAvoidArea(int32_t persistentId)8016 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8017 {
8018 auto task = [this, persistentId] {
8019 bool needUpdate = false;
8020 auto sceneSession = GetSceneSession(persistentId);
8021 if (sceneSession == nullptr) {
8022 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8023 return;
8024 }
8025 WindowType type = sceneSession->GetWindowType();
8026 if (sceneSession->IsImmersiveType()) {
8027 UpdateAvoidSessionAvoidArea(type, needUpdate);
8028 } else {
8029 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8030 }
8031 if (needUpdate) {
8032 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8033 }
8034 return;
8035 };
8036 taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8037 return;
8038 }
8039
UpdateAvoidAreaByType(int32_t persistentId,AvoidAreaType type)8040 void SceneSessionManager::UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)
8041 {
8042 auto task = [this, persistentId, type] {
8043 auto sceneSession = GetSceneSession(persistentId);
8044 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8045 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is nullptr or invisible", persistentId);
8046 return;
8047 }
8048 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8049 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d has no listener, no need update", persistentId);
8050 return;
8051 }
8052 if (sceneSession->IsImmersiveType()) {
8053 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is immersive type", persistentId);
8054 return;
8055 }
8056 auto avoidArea = sceneSession->GetAvoidAreaByType(type);
8057 if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && !CheckAvoidAreaForAINavigationBar(
8058 isAINavigationBarVisible_, avoidArea, sceneSession->GetSessionRect().height_)) {
8059 return;
8060 }
8061 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, type);
8062 };
8063 taskScheduler_->PostAsyncTask(task, "UpdateAvoidAreaByType:PID:" + std::to_string(persistentId));
8064 }
8065
UpdateGestureBackEnabled(int32_t persistentId)8066 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8067 {
8068 auto task = [this, persistentId] {
8069 auto sceneSession = GetSceneSession(persistentId);
8070 if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8071 TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8072 return;
8073 }
8074 auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8075 if (needEnableGestureBack) {
8076 gestureBackEnableWindowIdSet_.erase(persistentId);
8077 } else {
8078 gestureBackEnableWindowIdSet_.insert(persistentId);
8079 }
8080 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8081 sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8082 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8083 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8084 enterRecent_.load() || !sceneSession->IsFocused()) {
8085 needEnableGestureBack = true;
8086 }
8087 if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8088 gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8089 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8090 } else {
8091 TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8092 }
8093 };
8094 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8095 }
8096
UpdateOccupiedAreaIfNeed(const int32_t & persistentId)8097 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8098 {
8099 auto task = [this, persistentId]() {
8100 sptr<SceneSession> keyboardSession = nullptr;
8101 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8102 for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8103 auto sceneSession = item->second;
8104 if (sceneSession != nullptr &&
8105 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8106 keyboardSession = sceneSession;
8107 break;
8108 }
8109 }
8110 if (keyboardSession == nullptr) {
8111 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8112 return;
8113 }
8114 if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8115 return;
8116 }
8117
8118 keyboardSession->OnCallingSessionUpdated();
8119 return;
8120 };
8121 taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8122 return;
8123 }
8124
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)8125 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8126 {
8127 TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8128 isVisible, persistentId);
8129 auto task = [this, persistentId, isVisible] {
8130 auto sceneSession = GetSceneSession(persistentId);
8131 if (sceneSession == nullptr) {
8132 TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8133 return;
8134 }
8135 sceneSession->SetIsStatusBarVisible(isVisible);
8136 };
8137 taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8138 return WSError::WS_OK;
8139 }
8140
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)8141 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8142 {
8143 WLOGFI("isVisible: %{public}u, "
8144 "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8145 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8146 auto task = [this, isVisible, barArea, displayId]() {
8147 bool isNeedNotify = isAINavigationBarVisible_ != isVisible;
8148 {
8149 std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8150 bool isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8151 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8152 currAINavigationBarAreaMap_[displayId] != barArea;
8153 if (isNeedUpdate) {
8154 isAINavigationBarVisible_ = isVisible;
8155 currAINavigationBarAreaMap_.clear();
8156 currAINavigationBarAreaMap_[displayId] = barArea;
8157 }
8158 if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8159 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8160 currAINavigationBarAreaMap_[displayId] = WSRect();
8161 }
8162 }
8163 if (isNeedNotify) {
8164 WLOGFI("NotifyAINavigationBar: enter: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8165 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8166 for (auto persistentId : avoidAreaListenerSessionSet_) {
8167 NotifySessionAINavigationBarChange(persistentId);
8168 }
8169 }
8170 };
8171 taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
8172 return WSError::WS_OK;
8173 }
8174
NotifySessionAINavigationBarChange(int32_t persistentId)8175 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
8176 {
8177 auto sceneSession = GetSceneSession(persistentId);
8178 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8179 return;
8180 }
8181 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8182 if (!CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8183 sceneSession->GetSessionRect().height_)) {
8184 return;
8185 }
8186 WLOGFI("NotifyAINavigationBarShowStatus: persistentId: %{public}d, "
8187 "{%{public}d,%{public}d,%{public}d,%{public}d}", persistentId,
8188 avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
8189 avoidArea.bottomRect_.width_, avoidArea.bottomRect_.height_);
8190 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
8191 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8192 }
8193
GetAINavigationBarArea(uint64_t displayId)8194 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
8195 {
8196 std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8197 if (currAINavigationBarAreaMap_.count(displayId) == 0) {
8198 return {};
8199 }
8200 return currAINavigationBarAreaMap_[displayId];
8201 }
8202
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)8203 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
8204 {
8205 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8206 auto task = [this, persistentId, haveListener, callingPid]() {
8207 TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
8208 persistentId, haveListener);
8209 auto sceneSession = GetSceneSession(persistentId);
8210 if (sceneSession == nullptr) {
8211 TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
8212 return WSError::WS_DO_NOTHING;
8213 }
8214 if (callingPid != sceneSession->GetCallingPid()) {
8215 TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
8216 return WSError::WS_ERROR_INVALID_PERMISSION;
8217 }
8218 if (haveListener) {
8219 touchOutsideListenerSessionSet_.insert(persistentId);
8220 } else {
8221 touchOutsideListenerSessionSet_.erase(persistentId);
8222 }
8223 return WSError::WS_OK;
8224 };
8225 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
8226 }
8227
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)8228 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
8229 {
8230 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
8231 auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
8232 WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
8233 persistentId, haveListener);
8234 auto sceneSession = GetSceneSession(persistentId);
8235 if (sceneSession == nullptr) {
8236 WLOGFD("sceneSession is nullptr.");
8237 return WSError::WS_DO_NOTHING;
8238 }
8239 if (callingPid != sceneSession->GetCallingPid()) {
8240 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
8241 return WSError::WS_ERROR_INVALID_PERMISSION;
8242 }
8243 if (haveListener) {
8244 windowVisibilityListenerSessionSet_.insert(persistentId);
8245 sceneSession->NotifyWindowVisibility();
8246 } else {
8247 windowVisibilityListenerSessionSet_.erase(persistentId);
8248 }
8249 return WSError::WS_OK;
8250 };
8251 return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
8252 }
8253
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)8254 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
8255 {
8256 processVirtualPixelRatioChangeFunc_ = func;
8257 WLOGFI("SetVirtualPixelRatioChangeListener");
8258 }
8259
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8260 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8261 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8262 {
8263 if (displayInfo == nullptr) {
8264 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
8265 return;
8266 }
8267 auto task = [this, displayInfo]() {
8268 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8269 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
8270 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
8271 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
8272 displayInfo->GetWidth(), displayInfo->GetHeight()
8273 };
8274 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
8275 }
8276 for (const auto &item : sceneSessionMap_) {
8277 auto scnSession = item.second;
8278 if (scnSession == nullptr) {
8279 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
8280 continue;
8281 }
8282 SessionInfo sessionInfo = scnSession->GetSessionInfo();
8283 if (sessionInfo.isSystem_) {
8284 continue;
8285 }
8286 if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8287 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
8288 scnSession->UpdateDensity();
8289 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
8290 "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
8291 scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8292 }
8293 }
8294 UpdateDisplayRegion(displayInfo);
8295 return WSError::WS_OK;
8296 };
8297 taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
8298 }
8299
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8300 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8301 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8302 {
8303 if (displayInfo == nullptr) {
8304 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
8305 return;
8306 }
8307 auto task = [this, displayInfo]() {
8308 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8309 for (const auto &item : sceneSessionMap_) {
8310 auto scnSession = item.second;
8311 if (scnSession == nullptr) {
8312 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
8313 continue;
8314 }
8315 if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8316 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
8317 continue;
8318 }
8319 if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
8320 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
8321 scnSession->GetRotation() != displayInfo->GetRotation()) {
8322 scnSession->UpdateRotationAvoidArea();
8323 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
8324 "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
8325 item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8326 }
8327 scnSession->SetRotation(displayInfo->GetRotation());
8328 scnSession->UpdateOrientation();
8329 }
8330 UpdateDisplayRegion(displayInfo);
8331 return WSError::WS_OK;
8332 };
8333 taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
8334 }
8335
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)8336 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
8337 {
8338 if (displayInfo == nullptr) {
8339 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
8340 return;
8341 }
8342
8343 auto task = [displayInfo]() -> WSError {
8344 ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
8345 displayInfo->GetScaleX(),
8346 displayInfo->GetScaleY(),
8347 displayInfo->GetPivotX(),
8348 displayInfo->GetPivotY(),
8349 displayInfo->GetTranslateX(),
8350 displayInfo->GetTranslateY());
8351 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
8352 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
8353 return WSError::WS_OK;
8354 };
8355 return taskScheduler_->PostAsyncTask(task);
8356 }
8357
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8358 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8359 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8360 {
8361 WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
8362 switch (type) {
8363 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
8364 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
8365 displayInfo, displayInfoMap, type);
8366 break;
8367 }
8368 case DisplayStateChangeType::UPDATE_ROTATION: {
8369 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
8370 displayInfo, displayInfoMap, type);
8371 break;
8372 }
8373 case DisplayStateChangeType::UPDATE_SCALE: {
8374 SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
8375 break;
8376 }
8377 default:
8378 return;
8379 }
8380 }
8381
OnScreenshot(DisplayId displayId)8382 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
8383 {
8384 SceneSessionManager::GetInstance().OnScreenshot(displayId);
8385 }
8386
OnScreenshot(DisplayId displayId)8387 void SceneSessionManager::OnScreenshot(DisplayId displayId)
8388 {
8389 auto task = [this, displayId]() {
8390 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8391 for (const auto& iter : sceneSessionMap_) {
8392 auto sceneSession = iter.second;
8393 if (sceneSession == nullptr) {
8394 continue;
8395 }
8396 auto state = sceneSession->GetSessionState();
8397 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
8398 sceneSession->NotifyScreenshot();
8399 }
8400 }
8401 };
8402 taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
8403 }
8404
ClearSession(int32_t persistentId)8405 WSError SceneSessionManager::ClearSession(int32_t persistentId)
8406 {
8407 WLOGFI("id: %{public}d", persistentId);
8408 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8409 WLOGFE("The caller is not system-app, can not use system-api");
8410 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8411 }
8412 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8413 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8414 return WSError::WS_ERROR_INVALID_PERMISSION;
8415 }
8416 auto task = [this, persistentId]() {
8417 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8418 return ClearSession(sceneSession);
8419 };
8420 taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
8421 return WSError::WS_OK;
8422 }
8423
ClearSession(sptr<SceneSession> sceneSession)8424 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
8425 {
8426 WLOGFD("Enter");
8427 if (sceneSession == nullptr) {
8428 WLOGFE("session is nullptr");
8429 return WSError::WS_ERROR_INVALID_SESSION;
8430 }
8431 if (!IsSessionClearable(sceneSession)) {
8432 WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
8433 return WSError::WS_ERROR_INVALID_SESSION;
8434 }
8435 const WSError errCode = sceneSession->Clear();
8436 return errCode;
8437 }
8438
ClearAllSessions()8439 WSError SceneSessionManager::ClearAllSessions()
8440 {
8441 WLOGFD("Enter");
8442 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8443 WLOGFE("The caller is not system-app, can not use system-api");
8444 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8445 }
8446 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8447 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8448 return WSError::WS_ERROR_INVALID_PERMISSION;
8449 }
8450 auto task = [this]() {
8451 std::vector<sptr<SceneSession>> sessionVector;
8452 GetAllClearableSessions(sessionVector);
8453 for (uint32_t i = 0; i < sessionVector.size(); i++) {
8454 ClearSession(sessionVector[i]);
8455 }
8456 return WSError::WS_OK;
8457 };
8458 taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
8459 return WSError::WS_OK;
8460 }
8461
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)8462 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
8463 {
8464 WLOGFD("Enter");
8465 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8466 for (const auto &item : sceneSessionMap_) {
8467 auto scnSession = item.second;
8468 if (IsSessionClearable(scnSession)) {
8469 sessionVector.push_back(scnSession);
8470 }
8471 }
8472 }
8473
LockSession(int32_t sessionId)8474 WSError SceneSessionManager::LockSession(int32_t sessionId)
8475 {
8476 WLOGFI("id: %{public}d", sessionId);
8477 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8478 WLOGFE("The caller is not system-app, can not use system-api");
8479 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8480 }
8481 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8482 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8483 return WSError::WS_ERROR_INVALID_PERMISSION;
8484 }
8485 auto task = [this, sessionId]() {
8486 auto sceneSession = GetSceneSession(sessionId);
8487 if (sceneSession == nullptr) {
8488 WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
8489 return WSError::WS_ERROR_INVALID_PARAM;
8490 }
8491 sceneSession->SetSessionInfoLockedState(true);
8492 return WSError::WS_OK;
8493 };
8494 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
8495 }
8496
UnlockSession(int32_t sessionId)8497 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
8498 {
8499 WLOGFI("id: %{public}d", sessionId);
8500 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8501 WLOGFE("The caller is not system-app, can not use system-api");
8502 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8503 }
8504 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8505 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8506 return WSError::WS_ERROR_INVALID_PERMISSION;
8507 }
8508 auto task = [this, sessionId]() {
8509 auto sceneSession = GetSceneSession(sessionId);
8510 if (sceneSession == nullptr) {
8511 WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
8512 return WSError::WS_ERROR_INVALID_PARAM;
8513 }
8514 sceneSession->SetSessionInfoLockedState(false);
8515 return WSError::WS_OK;
8516 };
8517 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
8518 }
8519
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)8520 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
8521 {
8522 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8523 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8524 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8525 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8526 }
8527 if (!SessionPermission::VerifySessionPermission()) {
8528 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8529 return WSError::WS_ERROR_INVALID_PERMISSION;
8530 }
8531
8532 return WSError::WS_OK;
8533 }
8534
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)8535 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
8536 std::vector<int32_t>& result)
8537 {
8538 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8539 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8540 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8541 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8542 }
8543 if (!SessionPermission::VerifySessionPermission()) {
8544 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8545 return WSError::WS_ERROR_INVALID_PERMISSION;
8546 }
8547
8548 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
8549 return WSError::WS_OK;
8550 }
8551
IsSessionClearable(sptr<SceneSession> scnSession)8552 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
8553 {
8554 if (scnSession == nullptr) {
8555 WLOGFI("scnSession is nullptr");
8556 return false;
8557 }
8558 SessionInfo sessionInfo = scnSession->GetSessionInfo();
8559 if (sessionInfo.abilityInfo == nullptr) {
8560 WLOGFI("scnSession abilityInfo is nullptr");
8561 return false;
8562 }
8563 if (sessionInfo.abilityInfo->excludeFromMissions && !scnSession->IsAnco()) {
8564 WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
8565 return false;
8566 }
8567 if (sessionInfo.abilityInfo->unclearableMission) {
8568 WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
8569 return false;
8570 }
8571 if (sessionInfo.isSystem_) {
8572 WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
8573 return false;
8574 }
8575 if (sessionInfo.lockedState) {
8576 WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
8577 return false;
8578 }
8579
8580 return true;
8581 }
8582
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)8583 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
8584 const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
8585 {
8586 WLOGFI("type: %{public}d", type);
8587 auto isSaCall = SessionPermission::IsSACalling();
8588 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8589 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8590 return WSError::WS_ERROR_INVALID_PERMISSION;
8591 }
8592 if (!CheckCollaboratorType(type)) {
8593 WLOGFW("collaborator register failed, invalid type.");
8594 return WSError::WS_ERROR_INVALID_TYPE;
8595 }
8596 {
8597 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8598 collaboratorMap_[type] = impl;
8599 }
8600 auto task = [this] {
8601 if (abilityManagerCollaboratorRegisteredFunc_) {
8602 abilityManagerCollaboratorRegisteredFunc_();
8603 }
8604 };
8605 taskScheduler_->PostTask(task, __func__);
8606 return WSError::WS_OK;
8607 }
8608
UnregisterIAbilityManagerCollaborator(int32_t type)8609 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
8610 {
8611 WLOGFI("type: %{public}d", type);
8612 auto isSaCall = SessionPermission::IsSACalling();
8613 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8614 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8615 return WSError::WS_ERROR_INVALID_PERMISSION;
8616 }
8617 if (!CheckCollaboratorType(type)) {
8618 WLOGFE("collaborator unregister failed, invalid type.");
8619 return WSError::WS_ERROR_INVALID_TYPE;
8620 }
8621 {
8622 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8623 collaboratorMap_.erase(type);
8624 }
8625 return WSError::WS_OK;
8626 }
8627
CheckCollaboratorType(int32_t type)8628 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
8629 {
8630 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
8631 WLOGFD("type is invalid");
8632 return false;
8633 }
8634 return true;
8635 }
8636
CheckIfReuseSession(SessionInfo & sessionInfo)8637 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
8638 {
8639 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
8640 sessionInfo.moduleName_);
8641 if (abilityInfo == nullptr) {
8642 WLOGFE("abilityInfo is nullptr!");
8643 return BrokerStates::BROKER_UNKOWN;
8644 }
8645 sessionInfo.abilityInfo = abilityInfo;
8646 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
8647 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
8648 collaboratorType = CollaboratorType::RESERVE_TYPE;
8649 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
8650 collaboratorType = CollaboratorType::OTHERS_TYPE;
8651 }
8652 if (!CheckCollaboratorType(collaboratorType)) {
8653 WLOGFW("checked not collaborator!");
8654 return BrokerStates::BROKER_UNKOWN;
8655 }
8656 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
8657 sessionInfo.collaboratorType_ = collaboratorType;
8658 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8659 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
8660 WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
8661 sessionInfo.reuse = true;
8662 } else {
8663 sessionInfo.reuse = false;
8664 }
8665 WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
8666 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
8667 return resultValue;
8668 }
8669
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)8670 BrokerStates SceneSessionManager::NotifyStartAbility(
8671 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
8672 {
8673 WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
8674 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8675 if (collaborator == nullptr) {
8676 return BrokerStates::BROKER_UNKOWN;
8677 }
8678 if (sessionInfo.want == nullptr) {
8679 WLOGFI("sessionInfo.want is nullptr, init");
8680 sessionInfo.want = std::make_shared<AAFwk::Want>();
8681 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
8682 sessionInfo.moduleName_);
8683 }
8684 auto accessTokenIDEx = sessionInfo.callingTokenId_;
8685 if (collaborator != nullptr) {
8686 containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
8687 std::chrono::system_clock::now().time_since_epoch()).count();
8688
8689 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8690 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
8691 WLOGFI("want affinity exit %{public}s.", affinity.c_str());
8692 return BrokerStates::BROKER_UNKOWN;
8693 }
8694 sessionInfo.want->SetParam("oh_persistentId", persistentId);
8695 int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
8696 currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
8697 WLOGFI("collaborator ret: %{public}d", ret);
8698 if (ret == 0) {
8699 return BrokerStates::BROKER_STARTED;
8700 } else {
8701 return BrokerStates::BROKER_NOT_START;
8702 }
8703 }
8704 return BrokerStates::BROKER_UNKOWN;
8705 }
8706
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)8707 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
8708 {
8709 if (sceneSession == nullptr) {
8710 WLOGFE("sceneSession is nullptr");
8711 return;
8712 }
8713 if (sessionInfo.want == nullptr) {
8714 WLOGFI("sessionInfo.want is nullptr");
8715 return;
8716 }
8717 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8718 if (collaborator == nullptr) {
8719 return;
8720 }
8721 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8722 if (abilitySessionInfo == nullptr) {
8723 WLOGFE("abilitySessionInfo is nullptr");
8724 return;
8725 }
8726 abilitySessionInfo->want = *(sessionInfo.want);
8727 if (collaborator != nullptr) {
8728 int32_t missionId = abilitySessionInfo->persistentId;
8729 std::string bundleName = sessionInfo.bundleName_;
8730 int64_t timestamp = containerStartAbilityTime_;
8731 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
8732 WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
8733 missionId, bundleName.c_str());
8734 collaborator->NotifyMissionCreated(abilitySessionInfo);
8735 }
8736 }
8737
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)8738 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
8739 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
8740 {
8741 WLOGFD("type: %{public}d", collaboratorType);
8742 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8743 if (collaborator != nullptr) {
8744 WLOGFI("called NotifyLoadAbility");
8745 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
8746 }
8747 }
8748
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)8749 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
8750 {
8751 WLOGFD("Enter");
8752 if (sceneSession == nullptr) {
8753 WLOGFE("sceneSession is nullptr");
8754 return;
8755 }
8756 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8757 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8758 if (collaborator != nullptr) {
8759 WLOGFI("called UpdateMissionInfo");
8760 collaborator->UpdateMissionInfo(abilitySessionInfo);
8761 }
8762 }
8763
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)8764 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
8765 {
8766 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8767 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8768 if (collaborator != nullptr) {
8769 WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
8770 collaborator->NotifyMoveMissionToForeground(persistentId);
8771 }
8772 }
8773
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)8774 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
8775 {
8776 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8777 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8778 if (collaborator != nullptr) {
8779 WLOGFI("called NotifyClearMission %{public}d", persistentId);
8780 collaborator->NotifyClearMission(persistentId);
8781 }
8782 }
8783
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)8784 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
8785 {
8786 if (sceneSession == nullptr) {
8787 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
8788 return false;
8789 }
8790 std::string sessionAffinity;
8791 TLOGI(WmsLogTag::WMS_LIFE, "call");
8792 if (sceneSession->GetSessionInfo().want != nullptr) {
8793 sessionAffinity = sceneSession->GetSessionInfo().want
8794 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8795 }
8796 if (sessionAffinity.empty()) {
8797 TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
8798 BrokerStates notifyReturn = NotifyStartAbility(
8799 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
8800 if (notifyReturn == BrokerStates::BROKER_NOT_START) {
8801 TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
8802 return false;
8803 }
8804 }
8805 if (sceneSession->GetSessionInfo().want != nullptr) {
8806 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
8807 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
8808 TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
8809 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
8810 sceneSession->GetSessionInfo().sessionAffinity.c_str());
8811 } else {
8812 TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
8813 }
8814 return true;
8815 }
8816
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)8817 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
8818 {
8819 if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
8820 return false;
8821 }
8822 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
8823 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
8824 return true;
8825 }
8826
AddWindowDragHotArea(uint32_t type,WSRect & area)8827 void SceneSessionManager::AddWindowDragHotArea(uint32_t type, WSRect& area)
8828 {
8829 WLOGFI("type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
8830 "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
8831 SceneSession::AddOrUpdateWindowDragHotArea(type, area);
8832 }
8833
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)8834 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
8835 {
8836 auto task = [this, persistentId, isMaximize]() -> WSError {
8837 WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
8838 auto sceneSession = GetSceneSession(persistentId);
8839 if (sceneSession == nullptr) {
8840 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
8841 return WSError::WS_ERROR_INVALID_WINDOW;
8842 }
8843 sceneSession->UpdateMaximizeMode(isMaximize);
8844 return WSError::WS_OK;
8845 };
8846 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
8847 return WSError::WS_OK;
8848 }
8849
GetIsLayoutFullScreen(bool & isLayoutFullScreen)8850 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
8851 {
8852 auto task = [this, &isLayoutFullScreen]() {
8853 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8854 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
8855 auto sceneSession = item->second;
8856 if (sceneSession == nullptr) {
8857 WLOGFE("Session is nullptr");
8858 continue;
8859 }
8860 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
8861 continue;
8862 }
8863 auto state = sceneSession->GetSessionState();
8864 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8865 continue;
8866 }
8867 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
8868 continue;
8869 }
8870 auto property = sceneSession->GetSessionProperty();
8871 if (property == nullptr) {
8872 WLOGFE("Property is nullptr");
8873 continue;
8874 }
8875 isLayoutFullScreen = property->IsLayoutFullScreen();
8876 auto persistentId = sceneSession->GetPersistentId();
8877 if (isLayoutFullScreen) {
8878 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
8879 return WSError::WS_OK;
8880 } else {
8881 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
8882 }
8883 }
8884 WLOGFD("No immersive window");
8885 return WSError::WS_OK;
8886 };
8887
8888 taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
8889 return WSError::WS_OK;
8890 }
8891
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)8892 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
8893 {
8894 auto scnSession = GetSceneSession(persistentId);
8895 if (!scnSession) {
8896 WLOGFE("session is nullptr");
8897 return WSError::WS_ERROR_INVALID_WINDOW;
8898 }
8899 auto fromScreenId = scnSession->GetSessionInfo().screenId_;
8900 scnSession->SetScreenId(screenId);
8901 auto sessionProperty = scnSession->GetSessionProperty();
8902 if (!sessionProperty) {
8903 WLOGFE("Property is null, synchronous screenId failed");
8904 return WSError::WS_ERROR_NULLPTR;
8905 }
8906 sessionProperty->SetDisplayId(screenId);
8907 WLOGFD("Session move display %{public}" PRIu64 " from %{public}" PRIu64, screenId, fromScreenId);
8908 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
8909 scnSession->NotifyDisplayMove(fromScreenId, screenId);
8910 scnSession->UpdateDensity();
8911 return WSError::WS_OK;
8912 }
8913
NotifyStackEmpty(int32_t persistentId)8914 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
8915 {
8916 TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
8917 auto task = [this, persistentId]() {
8918 auto scnSession = GetSceneSession(persistentId);
8919 if (!scnSession) {
8920 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
8921 return WSError::WS_ERROR_INVALID_WINDOW;
8922 }
8923 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
8924 return WSError::WS_OK;
8925 };
8926 taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
8927 return WSError::WS_OK;
8928 }
8929
OnImmersiveStateChange(bool & immersive)8930 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
8931 {
8932 immersive = SceneSessionManager::GetInstance().GetImmersiveState();
8933 }
8934
GetImmersiveState()8935 bool SceneSessionManager::GetImmersiveState()
8936 {
8937 auto task = [this] {
8938 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8939 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
8940 auto sceneSession = item->second;
8941 if (sceneSession == nullptr) {
8942 WLOGFE("Session is nullptr");
8943 continue;
8944 }
8945 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
8946 continue;
8947 }
8948 auto state = sceneSession->GetSessionState();
8949 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
8950 continue;
8951 }
8952 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
8953 continue;
8954 }
8955 auto property = sceneSession->GetSessionProperty();
8956 if (property == nullptr) {
8957 WLOGFE("Property is nullptr");
8958 continue;
8959 }
8960 auto sysBarProperty = property->GetSystemBarProperty();
8961 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
8962 WLOGI("GetImmersiveState, window is immersive. id:%{public}d", sceneSession->GetPersistentId());
8963 return true;
8964 } else {
8965 WLOGI("GetImmersiveState, statusBar is enabled. id:%{public}d", sceneSession->GetPersistentId());
8966 break;
8967 }
8968 }
8969 WLOGI("GetImmersiveState, not immersive");
8970 return false;
8971 };
8972 return taskScheduler_->PostSyncTask(task, "GetImmersiveState");
8973 }
8974
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)8975 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
8976 bool withAnimation)
8977 {
8978 session->NotifySessionForeground(reason, withAnimation);
8979 }
8980
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)8981 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
8982 bool withAnimation, bool isFromInnerkits)
8983 {
8984 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
8985 }
8986
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)8987 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
8988 {
8989 auto sceneSession = GetSceneSession(persistentId);
8990 if (sceneSession == nullptr) {
8991 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
8992 return WSError::WS_ERROR_INVALID_WINDOW;
8993 }
8994 return sceneSession->UpdateTitleInTargetPos(isShow, height);
8995 }
8996
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)8997 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
8998 {
8999 WLOGFI("AppAnrListener OnAppDebugStarted");
9000 if (debugInfos.empty()) {
9001 WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9002 return;
9003 }
9004 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
9005 }
9006
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9007 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9008 {
9009 WLOGFI("AppAnrListener OnAppDebugStoped");
9010 if (debugInfos.empty()) {
9011 WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9012 return;
9013 }
9014 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
9015 }
9016
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)9017 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9018 {
9019 if (!Session::IsScbCoreEnabled()) {
9020 return;
9021 }
9022 if (onFlushUIParamsFunc_ != nullptr) {
9023 onFlushUIParamsFunc_();
9024 }
9025 auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9026 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9027 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9028 {
9029 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9030 nextFlushCompletedCV_.notify_all();
9031 }
9032 std::vector<uint32_t> startingAppZOrderList;
9033 processingFlushUIParams_.store(true);
9034 {
9035 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9036 for (const auto& item : sceneSessionMap_) {
9037 auto sceneSession = item.second;
9038 if (sceneSession == nullptr) {
9039 continue;
9040 }
9041 if (sceneSession->GetSessionInfo().screenId_ != SCREEN_ID_INVALID &&
9042 sceneSession->GetSessionInfo().screenId_ != screenId) {
9043 continue;
9044 }
9045 auto iter = uiParams.find(sceneSession->GetPersistentId());
9046 if (iter != uiParams.end()) {
9047 if (sceneSession->GetSessionInfo().screenId_ == SCREEN_ID_INVALID) {
9048 sceneSession->SetScreenIdOnServer(screenId);
9049 }
9050 if ((systemConfig_.uiType_ == UI_TYPE_PHONE ||
9051 (systemConfig_.uiType_ == UI_TYPE_PAD && !systemConfig_.IsFreeMultiWindowMode())) &&
9052 sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
9053 startingAppZOrderList.push_back(iter->second.zOrder_);
9054 sceneSession->SetStartingBeforeVisible(false);
9055 }
9056 sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9057 } else {
9058 sessionMapDirty_ |= sceneSession->UpdateUIParam();
9059 }
9060 }
9061 }
9062 processingFlushUIParams_.store(false);
9063
9064 // post process if dirty
9065 if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9066 static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9067 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9068 for (const auto& item : uiParams) {
9069 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f"
9070 " transY:%{public}f, needSync:%{public}d, intreactive:%{public}d", item.first, item.second.zOrder_,
9071 item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
9072 item.second.needSync_, item.second.interactive_);
9073 }
9074 ProcessUpdateLastFocusedAppId(startingAppZOrderList);
9075 ProcessFocusZOrderChange(sessionMapDirty_);
9076 PostProcessFocus();
9077 PostProcessProperty(sessionMapDirty_);
9078 NotifyAllAccessibilityInfo();
9079 AnomalyDetection::SceneZOrderCheckProcess();
9080 } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9081 PostProcessProperty(sessionMapDirty_);
9082 }
9083 FlushWindowInfoToMMI();
9084 sessionMapDirty_ = 0;
9085 {
9086 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9087 for (const auto& item : sceneSessionMap_) {
9088 auto sceneSession = item.second;
9089 if (sceneSession == nullptr) {
9090 continue;
9091 }
9092 sceneSession->ResetSizeChangeReasonIfDirty();
9093 sceneSession->ResetDirtyFlags();
9094 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9095 sceneSession->SetUIStateDirty(false);
9096 }
9097 }
9098 }
9099 };
9100 taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9101 }
9102
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)9103 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
9104 {
9105 TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu", lastFocusedAppSessionId_,
9106 zOrderList.size());
9107 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || zOrderList.empty()) {
9108 return;
9109 }
9110 auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId_);
9111 if (lastFocusedAppSession == nullptr) {
9112 return;
9113 }
9114 uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
9115 auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
9116 return zOrder > lastFocusedAppZOrder;
9117 });
9118 if (it != zOrderList.end()) {
9119 TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
9120 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
9121 }
9122 }
9123
ProcessFocusZOrderChange(uint32_t dirty)9124 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
9125 {
9126 if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9127 return;
9128 }
9129 if (systemConfig_.uiType_ != UI_TYPE_PHONE && systemConfig_.uiType_ != UI_TYPE_PAD) {
9130 return;
9131 }
9132 TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9133 auto focusedSession = GetSceneSession(focusedSessionId_);
9134 // only when it's from a high zOrder to a low zOrder
9135 if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9136 focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9137 return;
9138 }
9139 auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9140 if (voiceInteractionSession == nullptr) {
9141 return;
9142 }
9143 TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9144 "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9145 voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9146 if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9147 focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9148 return;
9149 }
9150 RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9151 }
9152
PostProcessFocus()9153 void SceneSessionManager::PostProcessFocus()
9154 {
9155 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9156 // priority process focus requests from top to bottom
9157 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9158 {
9159 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9160 for (auto& iter : sceneSessionMap_) {
9161 auto session = iter.second;
9162 if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9163 continue;
9164 }
9165 processingSessions.push_back(iter);
9166 }
9167 }
9168 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
9169 bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
9170 !rhs.second->GetPostProcessFocusState().isFocused_;
9171 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
9172 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
9173 return focusCmp || lhsZOrder > rhsZOrder;
9174 };
9175 std::sort(processingSessions.begin(), processingSessions.end(), cmp);
9176
9177 // only change focus one time
9178 bool focusChanged = false;
9179 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9180 auto session = iter->second;
9181 if (session == nullptr) {
9182 WLOGFE("session is nullptr");
9183 continue;
9184 }
9185 TLOGD(WmsLogTag::WMS_PIPELINE,
9186 "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
9187 session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
9188 session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
9189 if (focusChanged) {
9190 session->ResetPostProcessFocusState();
9191 continue;
9192 }
9193 WSError ret = WSError::WS_DO_NOTHING;
9194 if (session->GetPostProcessFocusState().isFocused_) {
9195 if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
9196 ret = RequestSessionFocusImmediately(session->GetPersistentId());
9197 } else {
9198 ret = RequestSessionFocus(session->GetPersistentId(), true,
9199 session->GetPostProcessFocusState().reason_);
9200 }
9201 } else {
9202 ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
9203 }
9204 session->ResetPostProcessFocusState();
9205 // if succeed then end process
9206 if (ret == WSError::WS_OK) {
9207 focusChanged = true;
9208 }
9209 }
9210 }
9211
PostProcessProperty(uint32_t dirty)9212 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
9213 {
9214 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
9215 if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9216 // only trigger update avoid area
9217 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9218 for (auto& iter : sceneSessionMap_) {
9219 auto session = iter.second;
9220 if (session == nullptr) {
9221 continue;
9222 }
9223 session->PostProcessNotifyAvoidArea();
9224 }
9225 return;
9226 }
9227
9228 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9229 {
9230 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9231 for (auto& iter : sceneSessionMap_) {
9232 auto session = iter.second;
9233 if (session == nullptr || !session->GetPostProcessProperty()) {
9234 continue;
9235 }
9236 processingSessions.push_back(iter);
9237 }
9238 }
9239
9240 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9241 auto session = iter->second;
9242 if (session == nullptr) {
9243 WLOGFE("session is nullptr");
9244 continue;
9245 }
9246 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
9247 UpdateForceHideState(session, session->GetSessionProperty(), true);
9248 HandleKeepScreenOn(session, session->IsKeepScreenOn());
9249 UpdatePrivateStateAndNotify(session->GetPersistentId());
9250 if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9251 ProcessSubSessionForeground(session);
9252 }
9253 session->SetPostProcessProperty(false);
9254 }
9255
9256 // update avoid area
9257 {
9258 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9259 for (auto& iter : sceneSessionMap_) {
9260 auto session = iter.second;
9261 if (session == nullptr) {
9262 continue;
9263 }
9264 session->PostProcessNotifyAvoidArea();
9265 }
9266 }
9267 }
9268
9269 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)9270 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
9271 {
9272 WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
9273 auto isSaCall = SessionPermission::IsSACalling();
9274 if (!isSaCall) {
9275 WLOGFE("The interface only support for sa call");
9276 return WSError::WS_ERROR_INVALID_PERMISSION;
9277 }
9278 auto task = [this, persistentId]() {
9279 auto sceneSession = GetSceneSession(persistentId);
9280 if (sceneSession == nullptr) {
9281 WLOGFE("session is nullptr");
9282 return WSError::WS_ERROR_INVALID_SESSION;
9283 }
9284 if (!IsSessionVisibleForeground(sceneSession)) {
9285 WLOGFD("session is not visible!");
9286 return WSError::WS_DO_NOTHING;
9287 }
9288 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
9289 RequestSessionFocus(persistentId, true, reason);
9290 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
9291 sceneSession->RaiseToAppTop();
9292 }
9293 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
9294 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
9295 WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
9296 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9297 }
9298 if (sceneSession == nullptr) {
9299 WLOGFE("parent session is nullptr");
9300 return WSError::WS_ERROR_INVALID_SESSION;
9301 }
9302 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9303 sceneSession->NotifyClick();
9304 return WSError::WS_OK;
9305 } else {
9306 WLOGFE("session is not app main window!");
9307 return WSError::WS_ERROR_INVALID_SESSION;
9308 }
9309 };
9310 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
9311 return WSError::WS_OK;
9312 }
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)9313 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
9314 {
9315 WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
9316 if (sourcePersistentId != focusedSessionId_) {
9317 WLOGFE("source session need be focused");
9318 return WSError::WS_ERROR_INVALID_OPERATION;
9319 }
9320 if (targetPersistentId == focusedSessionId_) {
9321 WLOGFE("target session has been focused");
9322 return WSError::WS_DO_NOTHING;
9323 }
9324 sptr<SceneSession> sourceSession = nullptr;
9325 WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
9326 if (ret != WSError::WS_OK) {
9327 return ret;
9328 }
9329 sptr<SceneSession> targetSession = nullptr;
9330 ret = GetAppMainSceneSession(targetSession, targetPersistentId);
9331 if (ret != WSError::WS_OK) {
9332 return ret;
9333 }
9334 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
9335 WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
9336 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
9337 return WSError::WS_ERROR_INVALID_CALLING;
9338 }
9339 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
9340 return WSError::WS_ERROR_INVALID_CALLING;
9341 }
9342 int32_t callingPid = IPCSkeleton::GetCallingPid();
9343 if (callingPid != targetSession->GetCallingPid()) {
9344 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
9345 return WSError::WS_ERROR_INVALID_CALLING;
9346 }
9347 targetSession->NotifyClick();
9348 FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
9349 return RequestSessionFocus(targetPersistentId, false, reason);
9350 }
9351
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)9352 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
9353 {
9354 sceneSession = GetSceneSession(persistentId);
9355 if (sceneSession == nullptr) {
9356 WLOGFE("session(%{public}d) is nullptr", persistentId);
9357 return WSError::WS_ERROR_INVALID_SESSION;
9358 }
9359 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9360 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
9361 WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
9362 return WSError::WS_ERROR_INVALID_CALLING;
9363 }
9364 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9365 if (sceneSession == nullptr) {
9366 WLOGFE("session(%{public}d) parent is nullptr", persistentId);
9367 return WSError::WS_ERROR_INVALID_SESSION;
9368 }
9369 }
9370 return WSError::WS_OK;
9371 }
9372
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)9373 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
9374 const float scaleParam)
9375 {
9376 auto sceneSession = GetSceneSession(persistentId);
9377 if (!sceneSession) {
9378 WLOGFE("get scene session is nullptr");
9379 return nullptr;
9380 }
9381
9382 wptr<SceneSession> weakSceneSession(sceneSession);
9383 auto task = [this, persistentId, scaleParam, weakSceneSession]() {
9384 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
9385 auto scnSession = weakSceneSession.promote();
9386 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
9387 if (scnSession == nullptr) {
9388 WLOGFE("session is nullptr");
9389 return pixelMap;
9390 }
9391
9392 if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
9393 scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
9394 pixelMap = scnSession->Snapshot(false, scaleParam);
9395 }
9396 if (!pixelMap) {
9397 WLOGFI("get local snapshot pixelmap start");
9398 pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
9399 }
9400 return pixelMap;
9401 };
9402 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
9403 }
9404
GetSceneSessionMap()9405 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
9406 {
9407 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
9408 {
9409 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9410 retSceneSessionMap = sceneSessionMap_;
9411 }
9412 EraseIf(retSceneSessionMap, [this](const auto& pair) {
9413 if (pair.second == nullptr) {
9414 return true;
9415 }
9416
9417 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
9418 if (pair.second->IsVisible()) {
9419 return false;
9420 }
9421 return true;
9422 }
9423
9424 if (pair.second->IsSystemInput()) {
9425 return false;
9426 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
9427 return false;
9428 }
9429
9430 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
9431 return true;
9432 }
9433 return false;
9434 });
9435 return retSceneSessionMap;
9436 }
9437
NotifyUpdateRectAfterLayout()9438 void SceneSessionManager::NotifyUpdateRectAfterLayout()
9439 {
9440 auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
9441 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
9442 if (transactionController) {
9443 rsTransaction = transactionController->GetRSTransaction();
9444 }
9445 auto task = [this, rsTransaction]() {
9446 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9447 for (auto& iter: sceneSessionMap_) {
9448 auto sceneSession = iter.second;
9449 if (sceneSession && sceneSession->IsDirtyWindow()) {
9450 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
9451 }
9452 }
9453 };
9454 // need sync task since animation transcation need
9455 return taskScheduler_->PostAsyncTask(task);
9456 }
9457
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)9458 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
9459 {
9460 if (!SessionPermission::IsSystemCalling()) {
9461 WLOGFE("GetVisibilityWindowInfo permission denied!");
9462 return WMError::WM_ERROR_NOT_SYSTEM_APP;
9463 }
9464 auto task = [this, &infos]() {
9465 for (auto [surfaceId, _] : lastVisibleData_) {
9466 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9467 if (session == nullptr) {
9468 continue;
9469 }
9470 WSRect hostRect = session->GetSessionRect();
9471 Rect rect = {hostRect.posX_, hostRect.posY_,
9472 static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
9473 auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
9474 session->GetSessionProperty());
9475 infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
9476 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
9477 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_));
9478 }
9479 return WMError::WM_OK;
9480 };
9481 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
9482 }
9483
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)9484 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
9485 {
9486 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9487 for (const auto& [id, session] : sceneSessionMap_) {
9488 if (session == nullptr) {
9489 continue;
9490 }
9491 uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
9492 windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
9493 }
9494 }
9495
FlushWindowInfoToMMI(const bool forceFlush)9496 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
9497 {
9498 auto task = [this, forceFlush] {
9499 if (isUserBackground_) {
9500 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
9501 return;
9502 }
9503 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
9504 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
9505 };
9506 taskScheduler_->PostAsyncTask(task);
9507 }
9508
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)9509 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
9510 int32_t& parentId)
9511 {
9512 // This function should be called in task
9513 auto iter = extSessionInfoMap_.find(token);
9514 if (iter == extSessionInfoMap_.end()) {
9515 return false;
9516 }
9517 persistentId = iter->second.persistentId;
9518 parentId = iter->second.parentId;
9519 return true;
9520 }
9521
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession)9522 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)
9523 {
9524 auto task = [this, remoteExtSession]() {
9525 auto iter = remoteExtSessionMap_.find(remoteExtSession);
9526 if (iter == remoteExtSessionMap_.end()) {
9527 TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
9528 return;
9529 }
9530 int32_t persistentId = INVALID_SESSION_ID;
9531 int32_t parentId = INVALID_SESSION_ID;
9532 if (!GetExtensionWindowIds(iter->second, persistentId, parentId)) {
9533 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9534 return;
9535 }
9536
9537 TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
9538 persistentId, parentId);
9539 auto sceneSession = GetSceneSession(parentId);
9540 if (sceneSession != nullptr) {
9541 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
9542 sceneSession->RemoveExtWindowFlags(persistentId);
9543 if (oldFlags.hideNonSecureWindowsFlag) {
9544 HandleSecureSessionShouldHide(sceneSession);
9545 }
9546 if (oldFlags.waterMarkFlag) {
9547 CheckAndNotifyWaterMarkChangedResult();
9548 }
9549 if (oldFlags.privacyModeFlag) {
9550 UpdatePrivateStateAndNotify(parentId);
9551 }
9552 sceneSession->RemoveModalUIExtension(persistentId);
9553 sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
9554 } else {
9555 ExtensionWindowFlags actions;
9556 actions.SetAllActive();
9557 HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
9558 }
9559 extSessionInfoMap_.erase(iter->second);
9560 remoteExtSessionMap_.erase(iter);
9561 };
9562 taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
9563 }
9564
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)9565 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
9566 {
9567 auto pid = IPCSkeleton::GetCallingRealPid();
9568 auto task = [this, token, pid, rect]() {
9569 int32_t persistentId = INVALID_SESSION_ID;
9570 int32_t parentId = INVALID_SESSION_ID;
9571 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9572 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9573 return;
9574 }
9575 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
9576 "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
9577 pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
9578 auto parentSession = GetSceneSession(parentId);
9579 if (parentSession) {
9580 auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
9581 auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
9582 Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
9583 ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect };
9584 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
9585 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
9586 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
9587 parentSession->GetSessionGlobalRect().ToString().c_str());
9588 parentSession->UpdateModalUIExtension(extensionInfo);
9589 }
9590 };
9591 taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
9592 }
9593
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)9594 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
9595 {
9596 auto pid = IPCSkeleton::GetCallingRealPid();
9597 auto task = [this, token, pid, posX, posY]() {
9598 int32_t persistentId = INVALID_SESSION_ID;
9599 int32_t parentId = INVALID_SESSION_ID;
9600 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9601 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9602 return;
9603 }
9604 TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
9605 "parentId=%{public}d", pid, persistentId, parentId);
9606 auto parentSession = GetSceneSession(parentId);
9607 if (parentSession && parentSession->HasModalUIExtension()) {
9608 auto modalUIExtension = parentSession->GetLastModalUIExtensionEventInfo();
9609 if ((modalUIExtension.pid == pid) && (modalUIExtension.persistentId == persistentId)) {
9610 parentSession->ProcessPointDownSession(posX, posY);
9611 }
9612 }
9613 };
9614 taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
9615 }
9616
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId)9617 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
9618 const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)
9619 {
9620 auto pid = IPCSkeleton::GetCallingRealPid();
9621 auto task = [this, sessionStage, token, surfaceNodeId, pid]() {
9622 if (sessionStage == nullptr || token == nullptr) {
9623 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9624 return;
9625 }
9626 auto remoteExtSession = sessionStage->AsObject();
9627 if (remoteExtSession == nullptr) {
9628 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9629 return;
9630 }
9631 if (extensionDeath_ == nullptr) {
9632 TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
9633 return;
9634 }
9635 if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
9636 TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
9637 return;
9638 }
9639
9640 AAFwk::UIExtensionSessionInfo info;
9641 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
9642 if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
9643 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
9644 return;
9645 }
9646
9647 int32_t persistentId = info.persistentId;
9648 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
9649 UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
9650 TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
9651 "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
9652 surfaceNodeId, pid);
9653
9654 remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
9655 extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
9656
9657 auto parentSession = GetSceneSession(parentId);
9658 if (parentSession) {
9659 parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
9660 }
9661 if (usage == UIExtensionUsage::MODAL && parentSession) {
9662 ExtensionWindowEventInfo extensionInfo {
9663 .persistentId = persistentId,
9664 .pid = pid,
9665 };
9666 parentSession->AddModalUIExtension(extensionInfo);
9667 }
9668 };
9669 taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
9670 }
9671
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token)9672 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
9673 const sptr<IRemoteObject>& token)
9674 {
9675 TLOGI(WmsLogTag::WMS_UIEXT, "called");
9676 auto task = [this, sessionStage, token]() {
9677 if (sessionStage == nullptr || token == nullptr) {
9678 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9679 return;
9680 }
9681 auto remoteExtSession = sessionStage->AsObject();
9682 if (remoteExtSession == nullptr) {
9683 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9684 return;
9685 }
9686 auto iter = remoteExtSessionMap_.find(remoteExtSession);
9687 if (iter->second != token) {
9688 TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
9689 return;
9690 }
9691
9692 DestroyExtensionSession(remoteExtSession);
9693 };
9694 taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
9695 }
9696
CalculateCombinedExtWindowFlags()9697 void SceneSessionManager::CalculateCombinedExtWindowFlags()
9698 {
9699 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
9700 combinedExtWindowFlags_.bitData = 0;
9701 for (const auto& iter: extWindowFlagsMap_) {
9702 combinedExtWindowFlags_.bitData |= iter.second.bitData;
9703 }
9704 specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
9705 }
9706
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)9707 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
9708 ExtensionWindowFlags actions)
9709 {
9710 auto iter = extWindowFlagsMap_.find(persistentId);
9711 // Each flag is false when inactive, 0 means all flags are inactive
9712 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
9713 ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
9714 if (newFlags.bitData == 0) {
9715 extWindowFlagsMap_.erase(persistentId);
9716 } else {
9717 extWindowFlagsMap_[persistentId] = newFlags;
9718 }
9719 CalculateCombinedExtWindowFlags();
9720 }
9721
HideNonSecureFloatingWindows()9722 void SceneSessionManager::HideNonSecureFloatingWindows()
9723 {
9724 bool shouldHide = false;
9725 {
9726 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9727 for (const auto& iter: sceneSessionMap_) {
9728 auto& session = iter.second;
9729 if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
9730 shouldHide = true;
9731 break;
9732 }
9733 }
9734 }
9735 if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
9736 TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
9737 shouldHide = true;
9738 }
9739 if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
9740 return;
9741 }
9742
9743 shouldHideNonSecureFloatingWindows_.store(shouldHide);
9744 for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
9745 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
9746 session->NotifyForceHideChange(shouldHide);
9747 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9748 session->GetWindowName().c_str(), persistentId, shouldHide);
9749 }
9750 }
9751 }
9752
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)9753 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
9754 {
9755 // don't let sub-window show when switching secure host window to background
9756 if (!sceneSession->IsSessionForeground()) {
9757 return;
9758 }
9759
9760 auto parentId = sceneSession->GetPersistentId();
9761 bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
9762 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9763 for (const auto& [persistentId, session] : sceneSessionMap_) {
9764 if (!session) {
9765 continue;
9766 }
9767 auto property = session->GetSessionProperty();
9768 if (!property || property->GetParentPersistentId() != parentId) {
9769 continue;
9770 }
9771
9772 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
9773 session->NotifyForceHideChange(shouldHide);
9774 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9775 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
9776 }
9777 }
9778 }
9779
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)9780 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
9781 {
9782 if (sceneSession == nullptr) {
9783 TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
9784 return WSError::WS_ERROR_INVALID_SESSION;
9785 }
9786
9787 HideNonSecureFloatingWindows();
9788 HideNonSecureSubWindows(sceneSession);
9789 return WSError::WS_OK;
9790 }
9791
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)9792 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
9793 ExtensionWindowFlags actions)
9794 {
9795 UpdateSpecialExtWindowFlags(persistentId, flags, actions);
9796 if (actions.waterMarkFlag) {
9797 CheckAndNotifyWaterMarkChangedResult();
9798 }
9799 if (actions.hideNonSecureWindowsFlag) {
9800 HideNonSecureFloatingWindows();
9801 }
9802 if (actions.privacyModeFlag) {
9803 UpdatePrivateStateAndNotifyForAllScreens();
9804 }
9805 }
9806
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)9807 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
9808 {
9809 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
9810 if (!SessionPermission::IsSystemCalling()) {
9811 TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
9812 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9813 }
9814 const auto callingPid = IPCSkeleton::GetCallingRealPid();
9815 auto task = [this, persistentId, shouldHide, callingPid]() {
9816 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9817 auto iter = sceneSessionMap_.find(persistentId);
9818 if (iter == sceneSessionMap_.end()) {
9819 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
9820 persistentId);
9821 return WSError::WS_ERROR_INVALID_SESSION;
9822 }
9823 auto sceneSession = iter->second;
9824 if (sceneSession == nullptr) {
9825 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
9826 return WSError::WS_ERROR_NULLPTR;
9827 }
9828 if (callingPid != sceneSession->GetCallingPid()) {
9829 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
9830 return WSError::WS_ERROR_INVALID_PERMISSION;
9831 }
9832 sceneSession->SetShouldHideNonSecureWindows(shouldHide);
9833 return HandleSecureSessionShouldHide(sceneSession);
9834 };
9835
9836 taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
9837 return WSError::WS_OK;
9838 }
9839
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const9840 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
9841 {
9842 auto ret = WSError::WS_OK;
9843 bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
9844 if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
9845 actions.hideNonSecureWindowsFlag = false;
9846 actions.waterMarkFlag = false;
9847 TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
9848 ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
9849 }
9850 auto needPrivacyWindow = actions.privacyModeFlag;
9851 if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
9852 actions.privacyModeFlag = false;
9853 TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
9854 ret = WSError::WS_ERROR_INVALID_PERMISSION;
9855 }
9856 return ret;
9857 }
9858
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)9859 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
9860 uint32_t extWindowActions)
9861 {
9862 ExtensionWindowFlags actions(extWindowActions);
9863 auto ret = CheckExtWindowFlagsPermission(actions);
9864 if (actions.bitData == 0) {
9865 return ret;
9866 }
9867
9868 ExtensionWindowFlags flags(extWindowFlags);
9869 auto task = [this, token, flags, actions]() {
9870 int32_t persistentId = INVALID_SESSION_ID;
9871 int32_t parentId = INVALID_SESSION_ID;
9872 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9873 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9874 return WSError::WS_ERROR_INVALID_OPERATION;
9875 }
9876
9877 TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
9878 "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
9879 auto sceneSession = GetSceneSession(parentId);
9880 if (sceneSession == nullptr) {
9881 TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
9882 parentId);
9883 HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
9884 return WSError::WS_OK;
9885 }
9886
9887 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
9888 sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
9889 auto newFlags = sceneSession->GetCombinedExtWindowFlags();
9890 if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
9891 HandleSecureSessionShouldHide(sceneSession);
9892 }
9893 if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
9894 CheckAndNotifyWaterMarkChangedResult();
9895 }
9896 if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
9897 UpdatePrivateStateAndNotify(parentId);
9898 }
9899 return WSError::WS_OK;
9900 };
9901
9902 taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
9903 return ret;
9904 }
9905
GetHostWindowRect(int32_t hostWindowId,Rect & rect)9906 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
9907 {
9908 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
9909 if (!SessionPermission::IsSystemCalling()) {
9910 TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
9911 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9912 }
9913 auto task = [this, hostWindowId, &rect]() {
9914 auto sceneSession = GetSceneSession(hostWindowId);
9915 if (sceneSession == nullptr) {
9916 TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
9917 return WSError::WS_ERROR_INVALID_SESSION;
9918 }
9919 WSRect hostRect = sceneSession->GetSessionRect();
9920 rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
9921 return WSError::WS_OK;
9922 };
9923 taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
9924 return WSError::WS_OK;
9925 }
9926
ReclaimPurgeableCleanMem()9927 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
9928 {
9929 #ifdef MEMMGR_WINDOW_ENABLE
9930 return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
9931 #else
9932 return -1;
9933 #endif
9934 }
9935
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)9936 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
9937 const std::vector<VisibleWindowNumInfo>& currentInfo)
9938 {
9939 if (lastInfo.size() != currentInfo.size()) {
9940 WLOGFE("last and current info is not Same");
9941 return false;
9942 }
9943 int sizeOfLastInfo = static_cast<int>(lastInfo.size());
9944 for (int i = 0; i < sizeOfLastInfo; i++) {
9945 if (lastInfo[i].displayId != currentInfo[i].displayId ||
9946 lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
9947 WLOGFE("last and current visible window num is not Same");
9948 return false;
9949 }
9950 }
9951 return true;
9952 }
9953
CacVisibleWindowNum()9954 void SceneSessionManager::CacVisibleWindowNum()
9955 {
9956 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
9957 {
9958 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9959 sceneSessionMapCopy = sceneSessionMap_;
9960 }
9961 std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
9962 bool isFullScreen = true;
9963 for (const auto& elem : sceneSessionMapCopy) {
9964 auto curSession = elem.second;
9965 if (curSession == nullptr) {
9966 continue;
9967 }
9968 bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
9969 curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
9970 if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
9971 continue;
9972 }
9973
9974 bool isWindowVisible = curSession->GetRSVisible();
9975 if (isWindowVisible) {
9976 auto windowMode = curSession->GetWindowMode();
9977 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
9978 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
9979 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
9980 isFullScreen = false;
9981 }
9982 int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
9983 auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
9984 [=](const VisibleWindowNumInfo& info) {
9985 return (static_cast<int32_t>(info.displayId)) == displayId;
9986 });
9987 if (it == visibleWindowNumInfo.end()) {
9988 visibleWindowNumInfo.push_back({displayId, 1});
9989 } else {
9990 it->visibleWindowNum++;
9991 }
9992 }
9993 }
9994 if (isFullScreen) {
9995 std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
9996 [](auto& info) { info.visibleWindowNum = 1; });
9997 }
9998 std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
9999 if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10000 SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10001 lastInfo_ = visibleWindowNumInfo;
10002 }
10003 }
10004
ReportWindowProfileInfos()10005 void SceneSessionManager::ReportWindowProfileInfos()
10006 {
10007 enum class WindowVisibleState : int32_t {
10008 FOCUSBLE = 0,
10009 VISIBLE,
10010 MINIMIZED,
10011 OCCLUSION
10012 };
10013 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10014 {
10015 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10016 sceneSessionMapCopy = sceneSessionMap_;
10017 }
10018 auto focusWindowId = GetFocusedSessionId();
10019 for (const auto& elem : sceneSessionMapCopy) {
10020 auto curSession = elem.second;
10021 if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10022 curSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10023 continue;
10024 }
10025 WindowProfileInfo windowProfileInfo;
10026 windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10027 windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10028 curSession->GetSessionProperty()->GetDisplayId());
10029 windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10030 if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10031 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10032 } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10033 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10034 } else if (!curSession->GetRSVisible()) {
10035 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10036 } else {
10037 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10038 }
10039 WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10040 WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10041 "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10042 windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10043 windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10044 }
10045 }
10046
GetCustomDecorHeight(int32_t persistentId)10047 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10048 {
10049 int32_t height = 0;
10050 auto sceneSession = GetSceneSession(persistentId);
10051 if (sceneSession == nullptr) {
10052 TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10053 return 0;
10054 }
10055 height = sceneSession->GetCustomDecorHeight();
10056 TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10057 return height;
10058 }
10059
removeFailRecoveredSession()10060 void SceneSessionManager::removeFailRecoveredSession()
10061 {
10062 for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10063 auto sceneSession = GetSceneSession(persistentId);
10064 if (sceneSession == nullptr) {
10065 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10066 continue;
10067 }
10068 if (!sceneSession->IsRecovered()) {
10069 TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10070 continue;
10071 }
10072 const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10073 if (!scnSessionInfo) {
10074 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr,persistentId = %{public}d", persistentId);
10075 continue;
10076 }
10077 TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10078 sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10079 }
10080 failRecoveredPersistentIdSet_.clear();
10081 }
10082
GetDisplayRegion(DisplayId displayId)10083 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10084 {
10085 if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10086 return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10087 }
10088 TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10089 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10090 if (display == nullptr) {
10091 TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10092 return nullptr;
10093 }
10094 auto displayInfo = display->GetDisplayInfo();
10095 if (displayInfo == nullptr) {
10096 TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
10097 return nullptr;
10098 }
10099 int32_t displayWidth = displayInfo->GetWidth();
10100 int32_t displayHeight = displayInfo->GetHeight();
10101 if (displayWidth == 0 || displayHeight == 0) {
10102 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10103 return nullptr;
10104 }
10105
10106 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10107 auto region = std::make_shared<SkRegion>(rect);
10108 displayRegionMap_[displayId] = region;
10109 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10110 return std::make_shared<SkRegion>(rect);
10111 }
10112
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)10113 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
10114 {
10115 if (displayInfo == nullptr) {
10116 TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
10117 return;
10118 }
10119 auto displayId = displayInfo->GetDisplayId();
10120 int32_t displayWidth = displayInfo->GetWidth();
10121 int32_t displayHeight = displayInfo->GetHeight();
10122 if (displayWidth == 0 || displayHeight == 0) {
10123 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10124 return;
10125 }
10126 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10127 auto region = std::make_shared<SkRegion>(rect);
10128 displayRegionMap_[displayId] = region;
10129 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10130 }
10131
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)10132 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
10133 {
10134 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10135 for (const auto& item : sceneSessionMap_) {
10136 auto sceneSession = item.second;
10137 if (sceneSession == nullptr) {
10138 continue;
10139 }
10140 if (Session::IsScbCoreEnabled()) {
10141 if (!sceneSession->IsVisibleForAccessibility()) {
10142 continue;
10143 }
10144 } else {
10145 if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
10146 continue;
10147 }
10148 }
10149 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10150 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10151 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10152 continue;
10153 }
10154 sceneSessionList.push_back(sceneSession);
10155 }
10156 }
10157
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)10158 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
10159 std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
10160 {
10161 for (const auto& sceneSession : sceneSessionList) {
10162 if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
10163 TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
10164 }
10165 }
10166 }
10167
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)10168 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
10169 {
10170 std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
10171 return a->GetZOrder() > b->GetZOrder();
10172 });
10173 std::vector<sptr<SceneSession>> result;
10174 std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
10175 for (const auto& sceneSession : sceneSessionList) {
10176 if (sceneSession == nullptr) {
10177 TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
10178 continue;
10179 }
10180 auto sessionProperty = sceneSession->GetSessionProperty();
10181 if (sessionProperty == nullptr) {
10182 TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
10183 continue;
10184 }
10185 std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
10186 auto displayId = sessionProperty->GetDisplayId();
10187 if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
10188 unaccountedSpace = unaccountedSpaceMap[displayId];
10189 } else {
10190 unaccountedSpace = GetDisplayRegion(displayId);
10191 if (unaccountedSpace == nullptr) {
10192 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
10193 continue;
10194 }
10195 unaccountedSpaceMap[displayId] = unaccountedSpace;
10196 }
10197 WSRect wsRect = sceneSession->GetSessionRect();
10198 SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
10199 .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
10200 SkRegion windowRegion(windowBounds);
10201 if (unaccountedSpace->quickReject(windowRegion)) {
10202 TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10203 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10204 continue;
10205 }
10206 if (!unaccountedSpace->intersects(windowRegion)) {
10207 TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10208 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10209 continue;
10210 }
10211 result.push_back(sceneSession);
10212 unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
10213 if (unaccountedSpace->isEmpty()) {
10214 break;
10215 }
10216 }
10217 sceneSessionList = result;
10218 }
10219
NotifyAllAccessibilityInfo()10220 void SceneSessionManager::NotifyAllAccessibilityInfo()
10221 {
10222 if (isUserBackground_) {
10223 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
10224 return;
10225 }
10226 std::vector<sptr<SceneSession>> sceneSessionList;
10227 GetAllSceneSessionForAccessibility(sceneSessionList);
10228 FilterSceneSessionCovered(sceneSessionList);
10229
10230 std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
10231 FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
10232
10233 for (const auto& item : accessibilityInfo) {
10234 TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, \
10235 bundle=%{public}s, bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
10236 item->wid_, item->innerWid_, item->bundleName_.c_str(),
10237 item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
10238 for (const auto& rect : item->touchHotAreas_) {
10239 TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d," \
10240 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
10241 }
10242 }
10243
10244 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
10245 WindowUpdateType::WINDOW_UPDATE_ALL);
10246 }
10247
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)10248 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
10249 const sptr<WindowSessionProperty>& property)
10250 {
10251 auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
10252 if (property == nullptr) {
10253 return windowStatus;
10254 }
10255 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
10256 windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
10257 if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
10258 windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
10259 }
10260 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
10261 windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
10262 } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
10263 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10264 } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
10265 windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
10266 }
10267 return windowStatus;
10268 }
10269
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)10270 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
10271 {
10272 if (!SessionPermission::IsStartedByInputMethod()) {
10273 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10274 return WMError::WM_ERROR_INVALID_PERMISSION;
10275 }
10276 auto scnSession = GetSceneSession(persistentId);
10277 if (scnSession == nullptr) {
10278 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10279 return WMError::WM_ERROR_NULLPTR;
10280 }
10281
10282 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10283 persistentId, scnSession->GetWindowType());
10284
10285 auto sessionProperty = scnSession->GetSessionProperty();
10286 if (sessionProperty == nullptr) {
10287 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10288 return WMError::WM_ERROR_INVALID_WINDOW;
10289 }
10290 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10291 auto callingSession = GetSceneSession(callingWindowId);
10292 if (callingSession == nullptr) {
10293 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10294 callingSession = GetSceneSession(focusedSessionId_);
10295 if (callingSession == nullptr) {
10296 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10297 return WMError::WM_ERROR_INVALID_WINDOW;
10298 }
10299 }
10300 if (callingSession->IsSystemSession()) {
10301 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10302 } else {
10303 windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
10304 callingSession->GetSessionProperty());
10305 }
10306 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
10307 persistentId, windowStatus);
10308 return WMError::WM_OK;
10309 }
10310
GetCallingWindowRect(int32_t persistentId,Rect & rect)10311 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
10312 {
10313 if (!SessionPermission::IsStartedByInputMethod()) {
10314 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10315 return WMError::WM_ERROR_INVALID_PERMISSION;
10316 }
10317 auto scnSession = GetSceneSession(persistentId);
10318 if (scnSession == nullptr) {
10319 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10320 return WMError::WM_ERROR_NULLPTR;
10321 }
10322 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10323 persistentId, scnSession->GetWindowType());
10324 auto sessionProperty = scnSession->GetSessionProperty();
10325 if (sessionProperty == nullptr) {
10326 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10327 return WMError::WM_ERROR_INVALID_WINDOW;
10328 }
10329 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10330 auto callingSession = GetSceneSession(callingWindowId);
10331 if (callingSession == nullptr) {
10332 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10333 callingSession = GetSceneSession(focusedSessionId_);
10334 if (callingSession == nullptr) {
10335 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10336 return WMError::WM_ERROR_INVALID_WINDOW;
10337 }
10338 }
10339 WSRect sessionRect = callingSession->GetSessionRect();
10340 rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
10341 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
10342 "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10343 return WMError::WM_OK;
10344 }
10345
GetWindowModeType(WindowModeType & windowModeType)10346 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
10347 {
10348 if (!SessionPermission::IsSACalling()) {
10349 WLOGFE("GetWindowModeType permission denied!");
10350 return WMError::WM_ERROR_INVALID_PERMISSION;
10351 }
10352 windowModeType = CheckWindowModeType();
10353 return WMError::WM_OK;
10354 }
10355
GetWindowStyleType(WindowStyleType & windowStyleType)10356 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
10357 {
10358 if (!SessionPermission::IsSACalling()) {
10359 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10360 return WMError::WM_ERROR_INVALID_PERMISSION;
10361 }
10362 auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
10363 if (isPC) {
10364 windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
10365 return WMError::WM_OK;
10366 }
10367 windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
10368 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
10369 return WMError::WM_OK;
10370 }
10371
CheckSceneZOrder()10372 void SceneSessionManager::CheckSceneZOrder()
10373 {
10374 auto task = [this]() {
10375 AnomalyDetection::SceneZOrderCheckProcess();
10376 };
10377 taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
10378 }
10379
NotifyEnterRecentTask(bool enterRecent)10380 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
10381 {
10382 TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
10383 enterRecent_.store(enterRecent);
10384 SetSystemAnimatedScenes(enterRecent ?
10385 SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
10386 auto task = [this] {
10387 for (auto persistentId : gestureBackEnableWindowIdSet_) {
10388 auto sceneSession = GetSceneSession(persistentId);
10389 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
10390 continue;
10391 }
10392 UpdateGestureBackEnabled(persistentId);
10393 }
10394 };
10395 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
10396 return WSError::WS_OK;
10397 }
10398
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)10399 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
10400 {
10401 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
10402 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
10403 return WMError::WM_ERROR_INVALID_PERMISSION;
10404 }
10405
10406 if (!topNInfo.empty() || (topNum <= 0)) {
10407 return WMError::WM_ERROR_INVALID_PARAM;
10408 }
10409
10410 TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
10411 auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
10412 if (session == nullptr) {
10413 return false;
10414 }
10415
10416 if (topNum == 0) {
10417 return true;
10418 }
10419
10420 if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
10421 TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
10422 return false;
10423 }
10424
10425 MainWindowInfo info;
10426 info.pid_ = session->GetCallingPid();
10427 info.bundleName_ = session->GetSessionInfo().bundleName_;
10428 topNInfo.push_back(info);
10429 topNum--;
10430 TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
10431 topNum, info.pid_, info.bundleName_.c_str());
10432 return false;
10433 };
10434 TraverseSessionTree(func, true);
10435
10436 return WMError::WM_OK;
10437 }
10438
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const10439 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
10440 {
10441 if (!infos.empty()) {
10442 TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
10443 return WMError::WM_ERROR_INVALID_PARAM;
10444 }
10445 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10446 TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
10447 return WMError::WM_ERROR_INVALID_PERMISSION;
10448 }
10449 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10450 for (const auto& iter : sceneSessionMap_) {
10451 auto& session = iter.second;
10452 if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
10453 continue;
10454 }
10455 MainWindowInfo info;
10456 auto abilityInfo = session->GetSessionInfo().abilityInfo;
10457 info.pid_ = session->GetCallingPid();
10458 info.bundleName_ = session->GetSessionInfo().bundleName_;
10459 info.persistentId_ = session->GetPersistentId();
10460 if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
10461 TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
10462 info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
10463 infos.push_back(info);
10464 } else if (abilityInfo != nullptr) {
10465 info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
10466 infos.push_back(info);
10467 TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
10468 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
10469 info.bundleName_.c_str(), info.bundleType_);
10470 }
10471 }
10472 return WMError::WM_OK;
10473 }
10474
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)10475 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
10476 std::vector<int32_t>& clearFailedIds)
10477 {
10478 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10479 TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
10480 return WMError::WM_ERROR_INVALID_PERMISSION;
10481 }
10482 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10483 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10484 return WMError::WM_ERROR_INVALID_PERMISSION;
10485 }
10486 clearFailedIds.clear();
10487 for (const auto persistentId : persistentIds) {
10488 auto sceneSession = GetSceneSession(persistentId);
10489 if (sceneSession == nullptr) {
10490 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
10491 clearFailedIds.push_back(persistentId);
10492 continue;
10493 }
10494 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10495 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10496 clearFailedIds.push_back(persistentId);
10497 continue;
10498 }
10499 sceneSession->Clear();
10500 TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
10501 }
10502 return WMError::WM_OK;
10503 }
10504
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)10505 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
10506 bool enable)
10507 {
10508 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
10509 width, height, density, enable);
10510
10511 DMHookInfo dmHookInfo;
10512 dmHookInfo.width_ = width;
10513 dmHookInfo.height_ = height;
10514 dmHookInfo.density_ = density;
10515 dmHookInfo.rotation_ = 0;
10516 dmHookInfo.enableHookRotation_ = false;
10517 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10518 return WMError::WM_OK;
10519 }
10520
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)10521 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
10522 {
10523 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
10524 "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
10525 hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
10526
10527 DMHookInfo dmHookInfo;
10528 dmHookInfo.width_ = hookInfo.width_;
10529 dmHookInfo.height_ = hookInfo.height_;
10530 dmHookInfo.density_ = hookInfo.density_;
10531 dmHookInfo.rotation_ = hookInfo.rotation_;
10532 dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
10533 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10534 return WMError::WM_OK;
10535 }
10536
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)10537 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
10538 {
10539 SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
10540 }
10541
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)10542 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
10543 {
10544 ScreenFoldData screenFoldData;
10545 WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
10546 if (ret != WMError::WM_OK) {
10547 return ret;
10548 }
10549 return CheckAndReportScreenFoldStatus(screenFoldData);
10550 }
10551
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)10552 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
10553 ScreenFoldData& screenFoldData)
10554 {
10555 if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
10556 TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
10557 return WMError::WM_DO_NOTHING;
10558 }
10559
10560 screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
10561 screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
10562 screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
10563 screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
10564 screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
10565 if (!screenFoldData.GetTypeCThermalWithUtil()) {
10566 TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
10567 return WMError::WM_DO_NOTHING;
10568 }
10569 AppExecFwk::ElementName element = {};
10570 WSError ret = GetFocusSessionElement(element);
10571 if (ret != WSError::WS_OK) {
10572 TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
10573 return WMError::WM_DO_NOTHING;
10574 }
10575 screenFoldData.SetFocusedPkgName(element.GetURI());
10576 return WMError::WM_OK;
10577 }
10578
CheckAndReportScreenFoldStatus(ScreenFoldData & data)10579 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
10580 {
10581 static ScreenFoldData lastScreenHalfFoldData;
10582 if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10583 lastScreenHalfFoldData = data;
10584 return WMError::WM_DO_NOTHING;
10585 }
10586 WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
10587 if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10588 if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
10589 lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
10590 } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
10591 // if stay at half-fold less than 15s, combine this change with last
10592 data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
10593 data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
10594 data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
10595 }
10596 lastScreenHalfFoldData.SetInvalid();
10597 }
10598 WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
10599 return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
10600 currentScreenFoldStatusReportRet;
10601 }
10602
10603 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)10604 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
10605 {
10606 if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
10607 return WMError::WM_DO_NOTHING;
10608 }
10609
10610 int32_t ret = HiSysEventWrite(
10611 OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
10612 "FOLDSCREEN_STATE_CHANGE",
10613 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
10614 "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
10615 "LASTFOLDSTATE", data.currentScreenFoldStatus_,
10616 "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
10617 "STATE", -1,
10618 "TIME", data.currentScreenFoldStatusDuration_,
10619 "ROTATION", data.screenRotation_,
10620 "PACKAGE", data.focusedPackageName_,
10621 "ANGLE", data.postureAngle_,
10622 "TYPECTHERMAL", data.typeCThermal_,
10623 "SCREENTHERMAL", -1,
10624 "SCANGLE", -1,
10625 "ISTENT", -1);
10626 if (ret != 0) {
10627 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
10628 return WMError::WM_DO_NOTHING;
10629 }
10630 return WMError::WM_OK;
10631 }
10632
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userid)10633 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
10634 {
10635 if (currentUserId_ != static_cast<int32_t>(userid)) {
10636 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64"", currentUserId_, userid);
10637 return;
10638 }
10639 auto secSurfaceInfoMap = secExtensionData->GetSecData();
10640 auto task = [secSurfaceInfoMap]()-> WSError {
10641 SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
10642 return WSError::WS_OK;
10643 };
10644 taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
10645 }
10646
RegisterSecSurfaceInfoListener()10647 void SceneSessionManager::RegisterSecSurfaceInfoListener()
10648 {
10649 auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
10650 this->UpdateSecSurfaceInfo(secExtensionData, userid);
10651 };
10652 TLOGI(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener");
10653 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
10654 TLOGE(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener failed");
10655 }
10656 }
10657
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)10658 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
10659 const AppForceLandscapeConfig& config)
10660 {
10661 if (bundleName.empty()) {
10662 TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
10663 return WSError::WS_ERROR_NULLPTR;
10664 }
10665 std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10666 appForceLandscapeMap_[bundleName] = config;
10667 TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
10668 bundleName.c_str(), config.mode_, config.homePage_.c_str());
10669 return WSError::WS_OK;
10670 }
10671
GetAppForceLandscapeConfig(const std::string & bundleName)10672 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
10673 {
10674 if (bundleName.empty()) {
10675 return {};
10676 }
10677 std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10678 if (appForceLandscapeMap_.empty() ||
10679 appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
10680 TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
10681 return {};
10682 }
10683 return appForceLandscapeMap_[bundleName];
10684 }
10685
TerminateSessionByPersistentId(int32_t persistentId)10686 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
10687 {
10688 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
10689 TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
10690 return WMError::WM_ERROR_INVALID_PERMISSION;
10691 }
10692 if (!SessionPermission::IsSystemAppCall()) {
10693 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
10694 return WMError::WM_ERROR_NOT_SYSTEM_APP;
10695 }
10696 auto sceneSession = GetSceneSession(persistentId);
10697 if (sceneSession == nullptr) {
10698 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
10699 return WMError::WM_ERROR_INVALID_PARAM;
10700 }
10701 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10702 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10703 return WMError::WM_ERROR_INVALID_PARAM;
10704 }
10705 sceneSession->Clear(true);
10706 TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
10707 return WMError::WM_OK;
10708 }
10709
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)10710 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
10711 {
10712 rootSceneProcessBackEventFunc_ = processBackEventFunc;
10713 TLOGI(WmsLogTag::WMS_EVENT, "called");
10714 }
10715
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)10716 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
10717 const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
10718 {
10719 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10720 TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
10721 return WMError::WM_ERROR_INVALID_PERMISSION;
10722 }
10723
10724 surfaceNodeIds.clear();
10725 TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
10726 for (auto persistentId : persistentIds) {
10727 TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
10728 auto sceneSession = GetSceneSession(persistentId);
10729 if (sceneSession == nullptr) {
10730 continue;
10731 }
10732 auto callingPid = sceneSession->GetCallingPid();
10733 auto surfaceNode = sceneSession->GetSurfaceNode();
10734 if (surfaceNode != nullptr && callingPid == pid) {
10735 surfaceNodeIds.push_back(surfaceNode->GetId());
10736 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
10737 if (leashWinSurfaceNode != nullptr) {
10738 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
10739 surfaceNodeIds.push_back(persistentId);
10740 }
10741 }
10742 }
10743
10744 return WMError::WM_OK;
10745 }
10746
ReleaseForegroundSessionScreenLock()10747 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
10748 {
10749 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10750 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
10751 return WMError::WM_ERROR_INVALID_PERMISSION;
10752 }
10753 #ifdef POWER_MANAGER_ENABLE
10754 auto task = [this] {
10755 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10756 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
10757 if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
10758 continue;
10759 }
10760 auto res = sceneSession->keepScreenLock_->UnLock();
10761 if (res != ERR_OK) {
10762 TLOGNE(WmsLogTag::DEFAULT,
10763 "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
10764 persistentId, sceneSession->GetWindowName().c_str(), res);
10765 return WMError::WM_ERROR_INVALID_OPERATION;
10766 }
10767 TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
10768 persistentId, sceneSession->GetWindowName().c_str());
10769 }
10770 return WMError::WM_OK;
10771 };
10772 return taskScheduler_->PostSyncTask(task, __func__);
10773 #else
10774 TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
10775 return WMError::WM_OK;
10776 #endif
10777 }
10778
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)10779 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
10780 {
10781 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
10782 auto task = [this, func] {
10783 closeTargetFloatWindowFunc_ = func;
10784 };
10785 taskScheduler_->PostTask(task, __func__);
10786 }
10787
CloseTargetFloatWindow(const std::string & bundleName)10788 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
10789 {
10790 if (!SessionPermission::IsSystemServiceCalling(false)) {
10791 TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
10792 return WMError::WM_ERROR_INVALID_PERMISSION;
10793 }
10794 auto task = [this, bundleName] {
10795 if (closeTargetFloatWindowFunc_) {
10796 TLOGNI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
10797 closeTargetFloatWindowFunc_(bundleName);
10798 }
10799 };
10800 taskScheduler_->PostTask(task, __func__);
10801 return WMError::WM_OK;
10802 }
10803
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)10804 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
10805 {
10806 SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
10807 }
10808
CloseTargetPiPWindow(const std::string & bundleName)10809 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
10810 {
10811 if (!SessionPermission::IsSystemServiceCalling(false)) {
10812 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
10813 return WMError::WM_ERROR_INVALID_PERMISSION;
10814 }
10815 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10816 for (const auto& iter : sceneSessionMap_) {
10817 auto& session = iter.second;
10818 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
10819 session->GetSessionInfo().bundleName_ == bundleName) {
10820 session->NotifyCloseExistPipWindow();
10821 break;
10822 }
10823 }
10824 return WMError::WM_OK;
10825 }
10826
GetCurrentPiPWindowInfo(std::string & bundleName)10827 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
10828 {
10829 if (!SessionPermission::IsSystemServiceCalling(false)) {
10830 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
10831 return WMError::WM_ERROR_INVALID_PERMISSION;
10832 }
10833 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10834 for (const auto& iter : sceneSessionMap_) {
10835 auto& session = iter.second;
10836 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
10837 bundleName = session->GetSessionInfo().bundleName_;
10838 return WMError::WM_OK;
10839 }
10840 }
10841 TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
10842 return WMError::WM_OK;
10843 }
10844
UpdateDarkColorModeToRS()10845 void SceneSessionManager::UpdateDarkColorModeToRS()
10846 {
10847 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
10848 if (appContext == nullptr) {
10849 TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
10850 return;
10851 }
10852 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
10853 if (config == nullptr) {
10854 TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
10855 return;
10856 }
10857 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
10858 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
10859 bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
10860 TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d",
10861 colorMode.c_str(), ret);
10862 }
10863
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)10864 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
10865 std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
10866 {
10867 if (!SessionPermission::IsSystemCalling()) {
10868 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
10869 return WMError::WM_ERROR_INVALID_PERMISSION;
10870 }
10871
10872 auto task = [this, windowIds, &windowDisplayIdMap] {
10873 for (const uint64_t windowId : windowIds) {
10874 sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
10875 if (session == nullptr) {
10876 continue;
10877 }
10878 sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
10879 if (sessionProperty == nullptr) {
10880 continue;
10881 }
10882 DisplayId displayId = sessionProperty->GetDisplayId();
10883 TLOGNI(WmsLogTag::DEFAULT, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
10884 windowId, displayId);
10885 windowDisplayIdMap.insert({windowId, displayId});
10886 }
10887 return WMError::WM_OK;
10888 };
10889 return taskScheduler_->PostSyncTask(task, __func__);
10890 }
10891
IsLastFrameLayoutFinished(bool & isLayoutFinished)10892 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
10893 {
10894 if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
10895 TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
10896 return WSError::WS_ERROR_NULLPTR;
10897 }
10898 isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
10899 return WSError::WS_OK;
10900 }
10901 } // namespace OHOS::Rosen