1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "session_manager/include/scene_session_manager.h"
17
18 #include <algorithm>
19 #include <securec.h>
20
21 #include <ability_context.h>
22 #include <ability_manager_client.h>
23 #include <bundlemgr/launcher_service.h>
24 #include <hisysevent.h>
25 #include <parameters.h>
26 #include <hitrace_meter.h>
27 #include "ffrt_inner.h"
28 #include "parameter.h"
29 #include "publish/scb_dump_subscriber.h"
30
31 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
32 #include <display_power_mgr_client.h>
33 #endif
34
35 #ifdef POWER_MANAGER_ENABLE
36 #include <power_mgr_client.h>
37 #endif
38
39 #ifdef RES_SCHED_ENABLE
40 #include "res_type.h"
41 #include "res_sched_client.h"
42 #endif
43 #include "scene_system_ability_listener.h"
44
45 #include "color_parser.h"
46 #include "common/include/session_permission.h"
47 #include "display_manager.h"
48 #include "scene_input_manager.h"
49 #include "session/host/include/main_session.h"
50 #include "session/host/include/scb_system_session.h"
51 #include "session/host/include/scene_persistent_storage.h"
52 #include "session/host/include/session_utils.h"
53 #include "session/host/include/sub_session.h"
54 #include "session_helper.h"
55 #include "window_helper.h"
56 #include "screen_session_manager_client/include/screen_session_manager_client.h"
57 #include "singleton_container.h"
58 #include "xcollie/watchdog.h"
59 #include "session_manager_agent_controller.h"
60 #include "distributed_client.h"
61 #include "softbus_bus_center.h"
62 #include "perform_reporter.h"
63 #include "dms_reporter.h"
64 #include "res_sched_client.h"
65 #include "res_type.h"
66 #include "anomaly_detection.h"
67 #include "hidump_controller.h"
68 #include "window_pid_visibility_info.h"
69 #include "session/host/include/multi_instance_manager.h"
70
71 #ifdef MEMMGR_WINDOW_ENABLE
72 #include "mem_mgr_client.h"
73 #include "mem_mgr_window_info.h"
74 #endif
75
76 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
77 #include "sec_comp_enhance_kit.h"
78 #endif
79
80 #ifdef IMF_ENABLE
81 #include <input_method_controller.h>
82 #endif // IMF_ENABLE
83
84 namespace OHOS::Rosen {
85 namespace {
86 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
87 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
88 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
89 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
90 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
91 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
92 constexpr const char* KEY_SESSION_ID = "com.ohos.param.sessionId";
93 constexpr uint32_t MAX_BRIGHTNESS = 255;
94 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
95 constexpr int32_t DEFAULT_USERID = -1;
96 constexpr int32_t SCALE_DIMENSION = 2;
97 constexpr int32_t TRANSLATE_DIMENSION = 2;
98 constexpr int32_t ROTAION_DIMENSION = 4;
99 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
100 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
101 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
102 const std::string EMPTY_DEVICE_ID = "";
103 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
104
105 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
106 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
107 constexpr int VALUE_MAX_WIDTH = 5;
108 constexpr int MAX_RESEND_TIMES = 6;
109 constexpr int ORIEN_MAX_WIDTH = 12;
110 constexpr int OFFSET_MAX_WIDTH = 8;
111 constexpr int SCALE_MAX_WIDTH = 8;
112 constexpr int PID_MAX_WIDTH = 8;
113 constexpr int PARENT_ID_MAX_WIDTH = 6;
114 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
115 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
116 const std::string ARG_DUMP_ALL = "-a";
117 const std::string ARG_DUMP_WINDOW = "-w";
118 const std::string ARG_DUMP_SCREEN = "-s";
119 const std::string ARG_DUMP_DISPLAY = "-d";
120 const std::string ARG_DUMP_PIPLINE = "-p";
121 const std::string ARG_DUMP_SCB = "-b";
122 const std::string ARG_DUMP_DETAIL = "-c";
123 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
124 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
125 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
126
127 constexpr int32_t FFRT_USER_INTERACTIVE_MAX_THREAD_NUM = 5;
128
129 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
130 {"unspecified", OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
131 {"landscape", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
132 {"portrait", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
133 {"follow_recent", OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
134 {"landscape_inverted", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
135 {"portrait_inverted", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
136 {"auto_rotation", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
137 {"auto_rotation_landscape", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
138 {"auto_rotation_portrait", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
139 {"auto_rotation_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
140 {"auto_rotation_landscape_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
141 {"auto_rotation_portrait_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
142 {"locked", OHOS::AppExecFwk::DisplayOrientation::LOCKED},
143 {"auto_rotation_unspecified", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
144 {"follow_desktop", OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
145 };
146
147 const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
148
GetCurrentTime()149 std::string GetCurrentTime()
150 {
151 struct timespec tn;
152 clock_gettime(CLOCK_REALTIME, &tn);
153 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
154 static_cast<uint64_t>(tn.tv_nsec);
155 return std::to_string(uTime);
156 }
Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)157 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
158 {
159 return a.first < b.first;
160 }
161
GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)162 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
163 {
164 if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
165 value = (*item.intsValue_)[0];
166 return true;
167 }
168 return false;
169 }
170
ConfigFfrtWorkerNum()171 int ConfigFfrtWorkerNum()
172 {
173 ffrt_worker_num_param qosConfig;
174 (void)memset_s(&qosConfig, sizeof(qosConfig), -1, sizeof(qosConfig));
175 qosConfig.effectLen = 1;
176 qosConfig.qosConfigArray[0].qos = ffrt_qos_user_interactive;
177 qosConfig.qosConfigArray[0].hardLimit = FFRT_USER_INTERACTIVE_MAX_THREAD_NUM;
178 return ffrt_set_qos_worker_num(&qosConfig);
179 }
180
GetPid()181 int32_t GetPid()
182 {
183 static int32_t pid = static_cast<int32_t>(getpid());
184 return pid;
185 }
186
187 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
188 public:
189 BundleStatusCallback() = default;
190 virtual ~BundleStatusCallback() = default;
191
192 void OnBundleStateChanged(const uint8_t installType,
193 const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
194
195 void OnBundleAdded(const std::string& bundleName, const int userId) override
196 {
197 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
198 }
199
200 void OnBundleUpdated(const std::string& bundleName, const int userId) override
201 {
202 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
203 }
204
205 void OnBundleRemoved(const std::string& bundleName, const int userId) override
206 {
207 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
208 }
209 };
210 } // namespace
211
CreateInstance()212 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
213 {
214 sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
215 sessionManager->Init();
216 return sessionManager;
217 }
218
GetInstance()219 SceneSessionManager& SceneSessionManager::GetInstance()
220 {
221 static sptr<SceneSessionManager> instance = CreateInstance();
222 return *instance;
223 }
224
SceneSessionManager()225 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
226 {
227 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
228 currentUserId_ = DEFAULT_USERID;
229 launcherService_ = sptr<AppExecFwk::LauncherService>::MakeSptr();
230 if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
231 WLOGFE("Failed to register bundle status callback.");
232 }
233
234 collaboratorDeathRecipient_ = sptr<AgentDeathRecipient>::MakeSptr(
235 [this](const sptr<IRemoteObject>& remoteObject) { this->ClearAllCollaboratorSessions(); });
236 }
237
~SceneSessionManager()238 SceneSessionManager::~SceneSessionManager()
239 {
240 ScbDumpSubscriber::UnSubscribe(scbDumpSubscriber_);
241 }
242
Init()243 void SceneSessionManager::Init()
244 {
245 auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
246 bool isScbCoreEnabled = (deviceType == "phone" || deviceType == "2in1" || deviceType == "tablet" ||
247 deviceType == "wearable") && system::GetParameter("persist.window.scbcore.enable", "1") == "1";
248 Session::SetScbCoreEnabled(isScbCoreEnabled);
249
250 constexpr uint64_t interval = 5 * 1000; // 5 second
251 if (HiviewDFX::Watchdog::GetInstance().AddThread(
252 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
253 WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
254 }
255
256 bundleMgr_ = GetBundleManager();
257
258 LoadWindowSceneXml();
259 LoadWindowParameter();
260 InitPrepareTerminateConfig();
261
262 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(sptr<DisplayChangeListener>::MakeSptr());
263
264 // create handler for inner command at server
265 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
266 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
267 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
268 if (ret != 0) {
269 WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
270 }
271 taskScheduler_->SetExportHandler(eventHandler_);
272
273 ret = ConfigFfrtWorkerNum();
274 TLOGI(WmsLogTag::WMS_MAIN, "FFRT user interactive qos max thread number: %{public}d, retcode: %{public}d",
275 FFRT_USER_INTERACTIVE_MAX_THREAD_NUM, ret);
276
277 listenerController_ = std::make_shared<SessionListenerController>();
278
279 scbSessionHandler_ = sptr<ScbSessionHandler>::MakeSptr();
280 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
281 StartWindowInfoReportLoop();
282 WLOGI("SSM init success.");
283
284 RegisterAppListener();
285 openDebugTrace_ = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
286 isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1") == "1";
287 SceneInputManager::GetInstance().Init();
288
289 // MMI window state error check
290 int32_t retCode = MMI::InputManager::GetInstance()->
291 RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
292 this->NotifyWindowStateErrorFromMMI(pid, persistentId);
293 });
294 TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
295
296 scbDumpSubscriber_ = ScbDumpSubscriber::Subscribe();
297 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
298 MultiInstanceManager::GetInstance().Init(bundleMgr_, taskScheduler_);
299 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
300 }
301 }
302
InitScheduleUtils()303 void SceneSessionManager::InitScheduleUtils()
304 {
305 #ifdef RES_SCHED_ENABLE
306 SCBThreadInfo threadInfo = {
307 .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
308 .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
309 };
310 std::unordered_map<std::string, std::string> payload {
311 { "pid", threadInfo.scbPid_ },
312 { "tid", threadInfo.scbTid_ },
313 { "uid", threadInfo.scbUid_ },
314 { "bundleName", threadInfo.scbBundleName_ },
315 };
316 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
317 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
318 auto task = [threadInfo = std::move(threadInfo)]() mutable {
319 threadInfo.ssmThreadName_ = "OS_SceneSession";
320 threadInfo.ssmTid_ = std::to_string(gettid());
321 const int32_t userInteraction = 2;
322 std::unordered_map<std::string, std::string> payload{
323 { "pid", threadInfo.scbPid_ },
324 { "tid", threadInfo.ssmTid_ },
325 { "uid", threadInfo.scbUid_ },
326 { "extType", "10002" },
327 { "cgroupPrio", "1" },
328 { "isSa", "0" },
329 { "threadName", threadInfo.ssmThreadName_ }
330 };
331 uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
332 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
333 TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
334 sptr<ISystemAbilityManager> systemAbilityManager =
335 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
336 if (!systemAbilityManager) {
337 TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
338 return;
339 }
340 auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
341 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
342 if (ret != ERR_OK) {
343 TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
344 }
345 };
346 taskScheduler_->PostAsyncTask(task, "changeQosTask");
347 #endif
348 }
349
RegisterAppListener()350 void SceneSessionManager::RegisterAppListener()
351 {
352 appAnrListener_ = sptr<AppAnrListener>::MakeSptr();
353 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
354 if (appMgrClient == nullptr) {
355 WLOGFE("appMgrClient is nullptr.");
356 } else {
357 auto ret = static_cast<int32_t>(appMgrClient->RegisterAppDebugListener(appAnrListener_));
358 WLOGFI("Register app debug listener, %{public}d.", ret);
359 }
360 }
361
LoadWindowParameter()362 void SceneSessionManager::LoadWindowParameter()
363 {
364 const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "HandsetSmartWindow");
365 if (multiWindowUIType == "HandsetSmartWindow") {
366 systemConfig_.windowUIType_ = WindowUIType::PHONE_WINDOW;
367 } else if (multiWindowUIType == "FreeFormMultiWindow") {
368 systemConfig_.windowUIType_ = WindowUIType::PC_WINDOW;
369 } else if (multiWindowUIType == "TabletSmartWindow") {
370 systemConfig_.windowUIType_ = WindowUIType::PAD_WINDOW;
371 } else {
372 WLOGFE("unknown multiWindowUIType:%{public}s.", multiWindowUIType.c_str());
373 }
374 appWindowSceneConfig_.multiWindowUIType_ = multiWindowUIType;
375 }
376
LoadWindowSceneXml()377 void SceneSessionManager::LoadWindowSceneXml()
378 {
379 if (WindowSceneConfig::LoadConfigXml()) {
380 if (WindowSceneConfig::GetConfig().IsMap()) {
381 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
382 }
383 ConfigWindowSceneXml();
384 } else {
385 WLOGFE("Load window scene xml failed");
386 }
387 ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
388 appWindowSceneConfig_.keyboardAnimationOut_);
389 }
390
InitPrepareTerminateConfig()391 void SceneSessionManager::InitPrepareTerminateConfig()
392 {
393 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
394 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
395 PREPARE_TERMINATE_ENABLE_SIZE);
396 WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
397 if (retSysParam > 0 && !std::strcmp(value, "true")) {
398 isPrepareTerminateEnable_ = true;
399 }
400 }
401
ConfigWindowSceneXml()402 void SceneSessionManager::ConfigWindowSceneXml()
403 {
404 const auto& config = WindowSceneConfig::GetConfig();
405 WindowSceneConfig::ConfigItem item = config["windowEffect"];
406 if (item.IsMap()) {
407 ConfigWindowEffect(item);
408 }
409 item = config["decor"];
410 if (item.IsMap()) {
411 ConfigDecor(item);
412 }
413
414 item = config["backgroundswitch"];
415 int32_t param = -1;
416 systemConfig_.backgroundswitch = GetSingleIntItem(item, param) && param == 1;
417 WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
418 item = config["defaultWindowMode"];
419 if (GetSingleIntItem(item, param) &&
420 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
421 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
422 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
423 }
424 item = config["defaultMaximizeMode"];
425 if (GetSingleIntItem(item, param) &&
426 (param == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
427 param == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
428 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(param);
429 }
430 item = config["keyboardAnimation"];
431 if (item.IsMap()) {
432 ConfigKeyboardAnimation(item);
433 }
434 item = config["maxFloatingWindowSize"];
435 if (GetSingleIntItem(item, param)) {
436 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(param);
437 }
438 item = config["windowAnimation"];
439 if (item.IsMap()) {
440 ConfigWindowAnimation(item);
441 }
442 item = config["startWindowTransitionAnimation"];
443 if (item.IsMap()) {
444 ConfigStartingWindowAnimation(item);
445 }
446 ConfigFreeMultiWindow();
447 ConfigWindowSizeLimits();
448 ConfigSnapshotScale();
449 ConfigWindowSceneXml(config);
450 }
451
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)452 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
453 {
454 WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
455 if (item.IsMap()) {
456 ConfigSystemUIStatusBar(item);
457 }
458 item = config["backgroundScreenLock"].GetProp("enable");
459 if (item.IsBool()) {
460 appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
461 }
462 item = config["rotationMode"];
463 if (item.IsString()) {
464 appWindowSceneConfig_.rotationMode_ = item.stringValue_;
465 }
466 item = config["immersive"];
467 if (item.IsMap()) {
468 ConfigWindowImmersive(item);
469 }
470 item = config["supportTypeFloatWindow"].GetProp("enable");
471 if (item.IsBool()) {
472 systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
473 }
474 }
475
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)476 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
477 {
478 AppWindowSceneConfig config;
479 WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
480 if (item.IsMap()) {
481 if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
482 appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
483 config.windowImmersive_.desktopStatusBarConfig_;
484 }
485 }
486 item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
487 if (item.IsMap()) {
488 if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
489 appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
490 config.windowImmersive_.upDownStatusBarConfig_;
491 }
492 }
493 item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
494 if (item.IsMap()) {
495 if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
496 appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
497 config.windowImmersive_.leftRightStatusBarConfig_;
498 }
499 }
500 }
501
ConfigStatusBar(const WindowSceneConfig::ConfigItem& config, StatusBarConfig& statusBarConfig)502 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
503 StatusBarConfig& statusBarConfig)
504 {
505 WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
506 if (item.IsBool()) {
507 statusBarConfig.showHide_ = item.boolValue_;
508 }
509 item = config["contentColor"];
510 if (item.IsString()) {
511 statusBarConfig.contentColor_ = item.stringValue_;
512 }
513 item = config["backgroundColor"];
514 if (item.IsString()) {
515 statusBarConfig.backgroundColor_ = item.stringValue_;
516 }
517 return true;
518 }
519
ConfigFreeMultiWindow()520 void SceneSessionManager::ConfigFreeMultiWindow()
521 {
522 const auto& config = WindowSceneConfig::GetConfig();
523 WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
524 if (freeMultiWindowConfig.IsMap()) {
525 auto supportItem = freeMultiWindowConfig.GetProp("enable");
526 if (supportItem.IsBool()) {
527 systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
528 }
529 auto item = freeMultiWindowConfig["decor"];
530 if (item.IsMap()) {
531 ConfigDecor(item, false);
532 }
533 int32_t param = -1;
534 item = freeMultiWindowConfig["defaultWindowMode"];
535 if (GetSingleIntItem(item, param) &&
536 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
537 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
538 systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
539 static_cast<WindowMode>(static_cast<uint32_t>(param));
540 }
541 item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
542 if (GetSingleIntItem(item, param) && (param > 0)) {
543 systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
544 }
545 }
546 }
547
LoadFreeMultiWindowConfig(bool enable)548 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
549 {
550 FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
551 if (enable) {
552 systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
553 systemConfig_.decorModeSupportInfo_ = freeMultiWindowConfig.decorModeSupportInfo_;
554 systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
555 } else {
556 const auto& config = WindowSceneConfig::GetConfig();
557 auto item = config["decor"];
558 if (item.IsMap()) {
559 ConfigDecor(item, true);
560 }
561 int32_t param = -1;
562 item = config["defaultWindowMode"];
563 if (GetSingleIntItem(item, param) &&
564 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
565 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
566 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
567 }
568 }
569 systemConfig_.freeMultiWindowEnable_ = enable;
570 rsInterface_.SetFreeMultiWindowStatus(enable);
571 }
572
GetSystemSessionConfig() const573 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
574 {
575 return systemConfig_;
576 }
577
SwitchFreeMultiWindow(bool enable)578 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
579 {
580 if (!systemConfig_.freeMultiWindowSupport_) {
581 TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
582 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
583 }
584 LoadFreeMultiWindowConfig(enable);
585 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
586 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
587 auto sceneSession = item->second;
588 if (sceneSession == nullptr) {
589 continue;
590 }
591 auto property = sceneSession->GetSessionProperty();
592 if (property == nullptr) {
593 continue;
594 }
595 bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
596 property->GetIsUIExtFirstSubWindow();
597 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
598 sceneSession->SwitchFreeMultiWindow(enable);
599 }
600 }
601 WindowStyleType type = enable ?
602 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
603 SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
604 return WSError::WS_OK;
605 }
606
GetFreeMultiWindowEnableState(bool& enable)607 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
608 {
609 enable = systemConfig_.freeMultiWindowEnable_;
610 return WSError::WS_OK;
611 }
612
SetSessionContinueState(const sptr<IRemoteObject>& token, const ContinueState& continueState)613 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject>& token,
614 const ContinueState& continueState)
615 {
616 TLOGI(WmsLogTag::DEFAULT, "Enter");
617 auto task = [this, token, continueState]() {
618 sptr <SceneSession> sceneSession = FindSessionByToken(token);
619 if (sceneSession == nullptr) {
620 TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
621 return WSError::WS_ERROR_INVALID_PARAM;
622 }
623 sceneSession->SetSessionInfoContinueState(continueState);
624 DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
625 static_cast<AAFwk::ContinueState>(continueState));
626 TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
627 sceneSession->GetPersistentId(), continueState);
628 return WSError::WS_OK;
629 };
630 return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
631 }
632
ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)633 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
634 {
635 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
636 if (item.IsBool()) {
637 if (mainConfig) {
638 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
639 } else {
640 systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
641 }
642 bool decorEnable = item.boolValue_;
643 uint32_t support = 0;
644 std::vector<std::string> supportedModes;
645 item = decorConfig["supportedMode"];
646 if (item.IsStrings()) {
647 supportedModes = *item.stringsValue_;
648 }
649 for (auto mode : supportedModes) {
650 if (mode == "fullscreen") {
651 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
652 } else if (mode == "floating") {
653 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
654 } else if (mode == "pip") {
655 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
656 } else if (mode == "split") {
657 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
658 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
659 } else {
660 WLOGFW("Invalid supporedMode");
661 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
662 break;
663 }
664 }
665 if (mainConfig && item.IsStrings()) {
666 systemConfig_.decorModeSupportInfo_ = support;
667 }
668 if (!mainConfig && item.IsStrings()) {
669 systemConfig_.freeMultiWindowConfig_.decorModeSupportInfo_ = support;
670 }
671 }
672 }
673
AddAlphaToColor(float alpha, std::string& color)674 static void AddAlphaToColor(float alpha, std::string& color)
675 {
676 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
677 return;
678 }
679
680 uint32_t alphaValue = 0xFF * alpha;
681 std::stringstream ss;
682 ss << std::hex << alphaValue;
683 std::string strAlpha = ss.str();
684 if (strAlpha.size() == 1) {
685 strAlpha.append(1, '0');
686 }
687
688 color.insert(1, strAlpha);
689 }
690
IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)691 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
692 {
693 return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
694 (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
695 AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
696 }
697
ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)698 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
699 {
700 AppWindowSceneConfig config;
701 // config corner radius
702 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
703 if (item.IsMap()) {
704 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
705 appWindowSceneConfig_ = config;
706 }
707 }
708
709 // config shadow
710 item = effectConfig["appWindows"]["shadow"]["focused"];
711 if (item.IsMap()) {
712 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
713 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
714 }
715 }
716
717 item = effectConfig["appWindows"]["shadow"]["unfocused"];
718 if (item.IsMap()) {
719 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
720 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
721 }
722 }
723
724 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
725 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
726
727 WLOGFI("Config window effect successfully");
728 }
729
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)730 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
731 {
732 std::map<std::string, float> stringToCornerRadius = {
733 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
734 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
735 };
736
737 if (item.IsString()) {
738 auto value = item.stringValue_;
739 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
740 out = stringToCornerRadius[value];
741 return true;
742 }
743 }
744 return false;
745 }
746
SetEnableInputEvent(bool enabled)747 void SceneSessionManager::SetEnableInputEvent(bool enabled)
748 {
749 TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
750 enableInputEvent_ = enabled;
751 }
752
IsInputEventEnabled()753 bool SceneSessionManager::IsInputEventEnabled()
754 {
755 return enableInputEvent_;
756 }
757
ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)758 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
759 {
760 for (const auto& persistentId : alivePersistentIds_) {
761 auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
762 if (it != recoveredPersistentIds.end()) {
763 continue;
764 }
765 auto sceneSession = GetSceneSession(persistentId);
766 if (sceneSession == nullptr) {
767 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
768 continue;
769 }
770 if (sceneSession->IsRecovered()) {
771 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
772 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
773 visibleWindowCountMap_.erase(sceneSession->GetCallingPid());
774 EraseSceneSessionAndMarkDirtyLockFree(persistentId);
775 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
776 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
777 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
778 }
779 }
780 }
781 }
782
UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)783 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
784 {
785 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
786 recoveredPersistentIds.size(), currentUserId_);
787
788 auto task = [this, recoveredPersistentIds]() {
789 ClearUnrecoveredSessions(recoveredPersistentIds);
790 std::list<AAFwk::SessionInfo> abilitySessionInfos;
791 for (const auto& persistentId : recoveredPersistentIds) {
792 if (failRecoveredPersistentIdSet_.count(persistentId)) {
793 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
794 continue;
795 }
796 auto sceneSession = GetSceneSession(persistentId);
797 if (sceneSession == nullptr) {
798 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
799 continue;
800 }
801 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
802 if (!abilitySessionInfo) {
803 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
804 continue;
805 }
806 TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
807 abilitySessionInfos.emplace_back(*abilitySessionInfo);
808 }
809 std::vector<int32_t> unrecoverableSessionIds;
810 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
811 abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
812 TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
813 unrecoverableSessionIds.size());
814 for (const auto& sessionId : unrecoverableSessionIds) {
815 auto sceneSession = GetSceneSession(sessionId);
816 if (sceneSession == nullptr) {
817 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
818 sessionId);
819 continue;
820 }
821 const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
822 if (!scnSessionInfo) {
823 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
824 continue;
825 }
826 TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
827 sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
828 }
829 RemoveFailRecoveredSession();
830 };
831 return taskScheduler_->PostAsyncTask(task, "UpdateSessionInfoBySCB");
832 }
833
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig, WindowShadowConfig& outShadow)834 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
835 WindowShadowConfig& outShadow)
836 {
837 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
838 if (item.IsString()) {
839 auto color = item.stringValue_;
840 uint32_t colorValue;
841 if (!ColorParser::Parse(color, colorValue)) {
842 return false;
843 }
844 outShadow.color_ = color;
845 }
846
847 item = shadowConfig["offsetX"];
848 if (item.IsFloats()) {
849 auto offsetX = *item.floatsValue_;
850 if (offsetX.size() != 1) {
851 return false;
852 }
853 outShadow.offsetX_ = offsetX[0];
854 }
855
856 item = shadowConfig["offsetY"];
857 if (item.IsFloats()) {
858 auto offsetY = *item.floatsValue_;
859 if (offsetY.size() != 1) {
860 return false;
861 }
862 outShadow.offsetY_ = offsetY[0];
863 }
864
865 item = shadowConfig["alpha"];
866 if (item.IsFloats()) {
867 auto alpha = *item.floatsValue_;
868 if (alpha.size() != 1 ||
869 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
870 return false;
871 }
872 outShadow.alpha_ = alpha[0];
873 }
874
875 item = shadowConfig["radius"];
876 if (item.IsFloats()) {
877 auto radius = *item.floatsValue_;
878 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
879 return false;
880 }
881 outShadow.radius_ = radius[0];
882 }
883
884 return true;
885 }
886
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item, KeyboardSceneAnimationConfig& config)887 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
888 KeyboardSceneAnimationConfig& config)
889 {
890 if (item.IsMap() && item.mapValue_->count("curve")) {
891 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
892 config.curveType_ = curveType;
893 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
894 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
895 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
896 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
897 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
898 }
899 }
900
901 const WindowSceneConfig::ConfigItem& duration = item["duration"];
902 if (duration.IsInts()) {
903 auto numbers = *duration.intsValue_;
904 if (numbers.size() == 1) {
905 config.duration_ = static_cast<uint32_t>(numbers[0]);
906 }
907 }
908 }
909
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)910 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
911 {
912 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
913 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
914
915 // config system animation
916 const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
917 systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
918 {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
919 appConfigIn.duration_);
920 const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
921 systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
922 {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
923 appConfigOut.duration_);
924 }
925
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn, KeyboardSceneAnimationConfig& animationOut)926 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
927 KeyboardSceneAnimationConfig& animationOut)
928 {
929 if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
930 TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
931 "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
932 systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
933 systemConfig_.animationOut_.duration_);
934 return;
935 }
936
937 // default animation curve params
938 constexpr char CURVETYPE[] = "interpolatingSpring";
939 constexpr float IN_CTRLX1 = 0.0f;
940 constexpr float OUT_CTRLX1 = 4.0f;
941 constexpr float CTRLY1 = 1.0f;
942 constexpr float CTRLX2 = 342.0f;
943 constexpr float CTRLY2 = 37.0f;
944 constexpr uint32_t DURATION = 150;
945 std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
946 std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
947
948 // update system config for client
949 systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
950 systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
951
952 // update app config for server
953 animationIn.curveType_ = CURVETYPE;
954 animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
955 animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
956 animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
957 animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
958 animationIn.duration_ = DURATION;
959
960 animationOut.curveType_ = CURVETYPE;
961 animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
962 animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
963 animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
964 animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
965 animationOut.duration_ = DURATION;
966 TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
967 }
968
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)969 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
970 {
971 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
972 if (item.IsMap() && item.mapValue_->count("curve")) {
973 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
974 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
975 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
976 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
977 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
978 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
979 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
980 }
981 }
982 item = windowAnimationConfig["timing"]["duration"];
983 if (item.IsInts() && item.intsValue_->size() == 1) {
984 auto duration = *item.intsValue_;
985 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
986 }
987 item = windowAnimationConfig["scale"];
988 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
989 auto scales = *item.floatsValue_;
990 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
991 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
992 }
993 item = windowAnimationConfig["rotation"];
994 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
995 auto rotations = *item.floatsValue_;
996 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
997 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
998 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
999 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1000 }
1001 item = windowAnimationConfig["translate"];
1002 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1003 auto translates = *item.floatsValue_;
1004 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1005 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1006 }
1007 item = windowAnimationConfig["opacity"];
1008 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1009 auto opacity = *item.floatsValue_;
1010 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1011 }
1012 }
1013
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)1014 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1015 {
1016 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1017 auto item = configItem.GetProp("enable");
1018 if (item.IsBool()) {
1019 config.enabled_ = item.boolValue_;
1020 }
1021 item = configItem["timing"];
1022 if (item.IsMap() && item.mapValue_->count("curve")) {
1023 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1024 }
1025 item = configItem["timing"]["duration"];
1026 if (item.IsInts() && item.intsValue_->size() == 1) {
1027 config.duration_ = (*item.intsValue_)[0];
1028 }
1029 item = configItem["opacityStart"];
1030 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1031 config.opacityStart_ = (*item.floatsValue_)[0];
1032 }
1033 item = configItem["opacityEnd"];
1034 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1035 config.opacityEnd_ = (*item.floatsValue_)[0];
1036 }
1037 }
1038
CreateCurve( const WindowSceneConfig::ConfigItem& curveConfig)1039 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1040 const WindowSceneConfig::ConfigItem& curveConfig)
1041 {
1042 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1043 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1044 static std::unordered_set<std::string> paramCurveSet = {
1045 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1046
1047 std::string curveName = "easeOut";
1048 const auto& nameItem = curveConfig.GetProp("name");
1049 if (!nameItem.IsString()) {
1050 return {curveName, {}};
1051 }
1052
1053 std::string name = nameItem.stringValue_;
1054 std::vector<float> curveParams;
1055
1056 if (paramCurveSet.find(name) != paramCurveSet.end()) {
1057 curveName = name;
1058 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1059 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1060 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1061 curveParams.begin());
1062 }
1063 } else {
1064 auto iter = curveSet.find(name);
1065 if (iter != curveSet.end()) {
1066 curveName = name;
1067 }
1068 }
1069
1070 return {curveName, curveParams};
1071 }
1072
ConfigWindowSizeLimits()1073 void SceneSessionManager::ConfigWindowSizeLimits()
1074 {
1075 const auto& config = WindowSceneConfig::GetConfig();
1076 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1077 if (item.IsMap()) {
1078 ConfigMainWindowSizeLimits(item);
1079 }
1080
1081 item = config["subWindowSizeLimits"];
1082 if (item.IsMap()) {
1083 ConfigSubWindowSizeLimits(item);
1084 }
1085 }
1086
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)1087 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1088 {
1089 auto item = mainWindowSizeConifg["miniWidth"];
1090 if (item.IsInts()) {
1091 auto numbers = *item.intsValue_;
1092 if (numbers.size() == 1) {
1093 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1094 }
1095 }
1096
1097 item = mainWindowSizeConifg["miniHeight"];
1098 if (item.IsInts()) {
1099 auto numbers = *item.intsValue_;
1100 if (numbers.size() == 1) {
1101 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1102 }
1103 }
1104 }
1105
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)1106 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1107 {
1108 auto item = subWindowSizeConifg["miniWidth"];
1109 if (item.IsInts()) {
1110 auto numbers = *item.intsValue_;
1111 if (numbers.size() == 1) {
1112 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1113 }
1114 }
1115
1116 item = subWindowSizeConifg["miniHeight"];
1117 if (item.IsInts()) {
1118 auto numbers = *item.intsValue_;
1119 if (numbers.size() == 1) {
1120 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1121 }
1122 }
1123 }
1124
ConfigSnapshotScale()1125 void SceneSessionManager::ConfigSnapshotScale()
1126 {
1127 const auto& config = WindowSceneConfig::GetConfig();
1128 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1129 if (item.IsFloats()) {
1130 auto snapshotScale = *item.floatsValue_;
1131 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1132 return;
1133 }
1134 snapshotScale_ = snapshotScale[0];
1135 }
1136 }
1137
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)1138 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1139 {
1140 TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1141 WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1142 if (item.IsInts() && item.intsValue_->size() == 1) {
1143 bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1144 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1145 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1146 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1147 }
1148
1149 item = statusBarConfig["immersiveStatusBarBgColor"];
1150 if (item.IsString()) {
1151 auto color = item.stringValue_;
1152 uint32_t colorValue;
1153 if (!ColorParser::Parse(color, colorValue)) {
1154 return;
1155 }
1156 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1157 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1158 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1159 }
1160
1161 item = statusBarConfig["immersiveStatusBarContentColor"];
1162 if (item.IsString()) {
1163 auto color = item.stringValue_;
1164 uint32_t colorValue;
1165 if (!ColorParser::Parse(color, colorValue)) {
1166 return;
1167 }
1168 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1169 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1170 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1171 }
1172 }
1173
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)1174 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1175 {
1176 rootSceneContextWeak_ = contextWeak;
1177 }
1178
GetRootSceneSession()1179 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1180 {
1181 auto task = [this] {
1182 if (rootSceneSession_ != nullptr) {
1183 return rootSceneSession_;
1184 }
1185 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1186 rootSceneSession_ = sptr<RootSceneSession>::MakeSptr();
1187 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1188 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1189 return rootSceneSession_;
1190 };
1191 return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1192 }
1193
GetRootSessionAvoidSessionRect(AvoidAreaType type)1194 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1195 {
1196 sptr<RootSceneSession> rootSession = GetRootSceneSession();
1197 if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1198 return {};
1199 }
1200 DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1201 std::vector<sptr<SceneSession>> sessionVector;
1202 switch (type) {
1203 case AvoidAreaType::TYPE_SYSTEM: {
1204 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1205 break;
1206 }
1207 case AvoidAreaType::TYPE_KEYBOARD: {
1208 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1209 break;
1210 }
1211 default: {
1212 TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1213 return {};
1214 }
1215 }
1216
1217 for (auto& session : sessionVector) {
1218 if (!session->IsVisible()) {
1219 continue;
1220 }
1221 const WSRect rect = session->GetSessionRect();
1222 TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1223 return rect;
1224 }
1225 return {};
1226 }
1227
GetSceneSession(int32_t persistentId)1228 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1229 {
1230 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1231 auto iter = sceneSessionMap_.find(persistentId);
1232 if (iter == sceneSessionMap_.end()) {
1233 WLOGFD("Error found scene session with id: %{public}d", persistentId);
1234 return nullptr;
1235 }
1236 return iter->second;
1237 }
1238
GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)1239 sptr<SceneSession> SceneSessionManager::GetSceneSessionByIdentityInfo(const SessionIdentityInfo& info)
1240 {
1241 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1242 for (const auto &item : sceneSessionMap_) {
1243 auto sceneSession = item.second;
1244 if (!sceneSession) {
1245 return nullptr;
1246 }
1247 if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1248 sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1249 sceneSession->GetSessionInfo().appInstanceKey_ != info.instanceKey_ ||
1250 sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1251 continue;
1252 }
1253 const auto& sessionModuleName = sceneSession->GetSessionInfo().moduleName_;
1254 const auto& sessionAbilityName = sceneSession->GetSessionInfo().abilityName_;
1255 if (info.isAtomicService_) {
1256 if ((sessionModuleName.empty() || sessionModuleName == info.moduleName_) &&
1257 (sessionAbilityName.empty() || sessionAbilityName == info.abilityName_)) {
1258 return sceneSession;
1259 }
1260 } else if (sessionModuleName == info.moduleName_ && sessionAbilityName == info.abilityName_) {
1261 return sceneSession;
1262 }
1263 }
1264 return nullptr;
1265 }
1266
GetSceneSessionByType(WindowType type)1267 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1268 {
1269 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1270 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1271 if (sceneSession && sceneSession->GetWindowType() == type) {
1272 return sceneSession;
1273 }
1274 }
1275 return nullptr;
1276 }
1277
GetSceneSessionVectorByType( WindowType type, uint64_t displayId)1278 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(
1279 WindowType type, uint64_t displayId)
1280 {
1281 if (displayId == DISPLAY_ID_INVALID) {
1282 TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1283 return {};
1284 }
1285 std::vector<sptr<SceneSession>> sceneSessionVector;
1286 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1287 for (const auto &item : sceneSessionMap_) {
1288 auto sceneSession = item.second;
1289 if (sceneSession->GetWindowType() == type &&
1290 sceneSession->GetSessionProperty() &&
1291 sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1292 sceneSessionVector.emplace_back(sceneSession);
1293 }
1294 }
1295
1296 return sceneSessionVector;
1297 }
1298
UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession, sptr<WindowSessionProperty> property)1299 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1300 sptr<WindowSessionProperty> property)
1301 {
1302 if (property == nullptr) {
1303 TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1304 return WSError::WS_ERROR_NULLPTR;
1305 }
1306 if (sceneSession == nullptr) {
1307 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1308 return WSError::WS_ERROR_NULLPTR;
1309 }
1310 auto parentPersistentId = property->GetParentPersistentId();
1311 sceneSession->SetParentPersistentId(parentPersistentId);
1312 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1313 auto parentSession = GetSceneSession(parentPersistentId);
1314 if (parentSession == nullptr) {
1315 TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1316 return WSError::WS_ERROR_NULLPTR;
1317 }
1318 parentSession->BindDialogSessionTarget(sceneSession);
1319 parentSession->BindDialogToParentSession(sceneSession);
1320 sceneSession->SetParentSession(parentSession);
1321 TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1322 sceneSession->GetPersistentId(), parentPersistentId);
1323 }
1324 return WSError::WS_OK;
1325 }
1326
CreateSpecificSessionCallback()1327 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1328 {
1329 sptr<SceneSession::SpecificSessionCallback> specificCb = sptr<SceneSession::SpecificSessionCallback>::MakeSptr();
1330 specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1331 return this->RequestSceneSession(sessionInfo, property);
1332 };
1333 specificCb->onDestroy_ = [this](const int32_t persistentId) {
1334 return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1335 };
1336 specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1337 this->ClearDisplayStatusBarTemporarilyFlags();
1338 };
1339 specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1340 this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1341 };
1342 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type, uint64_t displayId) {
1343 return this->GetSceneSessionVectorByType(type, displayId);
1344 };
1345 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1346 this->UpdateAvoidArea(persistentId);
1347 };
1348 specificCb->onUpdateAvoidAreaByType_ = [this](int32_t persistentId, AvoidAreaType type) {
1349 this->UpdateAvoidAreaByType(persistentId, type);
1350 };
1351 specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1352 this->UpdateOccupiedAreaIfNeed(persistentId);
1353 };
1354 specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1355 this->NotifyWindowInfoChange(persistentId, type);
1356 };
1357 specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1358 this->NotifyMMIWindowPidChange(windowId, startMoving);
1359 };
1360 specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1361 this->NotifySessionTouchOutside(persistentId);
1362 };
1363 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1364 return this->GetAINavigationBarArea(displayId);
1365 };
1366 specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1367 this->OnOutsideDownEvent(x, y);
1368 };
1369 specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1370 return this->HandleSecureSessionShouldHide(sceneSession);
1371 };
1372 specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1373 this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1374 };
1375 specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1376 this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1377 };
1378 specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1379 this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1380 };
1381 specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1382 this->UpdateGestureBackEnabled(persistentId);
1383 };
1384 return specificCb;
1385 }
1386
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)1387 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1388 {
1389 TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1390 auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1391 if (isSkip) {
1392 if (it == skipSurfaceNodeIds_.end()) {
1393 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1394 } else {
1395 return;
1396 }
1397 } else {
1398 if (it != skipSurfaceNodeIds_.end()) {
1399 skipSurfaceNodeIds_.erase(it);
1400 } else {
1401 return;
1402 }
1403 }
1404 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1405 }
1406
CreateKeyboardSessionCallback()1407 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1408 {
1409 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1410 sptr<KeyboardSession::KeyboardSessionCallback>::MakeSptr();
1411 keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1412 return this->GetSceneSession(persistentId);
1413 };
1414 keyboardCb->onGetFocusedSessionId_ = [this] {
1415 return this->GetFocusedSessionId();
1416 };
1417 keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1418 return keyboardCb;
1419 }
1420
CheckWindowId(int32_t windowId, int32_t& pid)1421 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1422 {
1423 if (!SessionPermission::IsSystemCalling()) {
1424 TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1425 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1426 }
1427
1428 auto task = [this, windowId, &pid]() -> WMError {
1429 pid = INVALID_PID;
1430 auto sceneSession = GetSceneSession(windowId);
1431 if (sceneSession == nullptr) {
1432 WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1433 return WMError::WM_ERROR_INVALID_WINDOW;
1434 }
1435 pid = sceneSession->GetCallingPid();
1436 WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1437 return WMError::WM_OK;
1438 };
1439 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1440 }
1441
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1442 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1443 {
1444 if (!isKeyboardPanelEnabled_) {
1445 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1446 return;
1447 }
1448 if (keyboardSession == nullptr) {
1449 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1450 return;
1451 }
1452 auto sessionProperty = keyboardSession->GetSessionProperty();
1453 if (sessionProperty == nullptr) {
1454 TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1455 return;
1456 }
1457 DisplayId displayId = sessionProperty->GetDisplayId();
1458 const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1459 sptr<SceneSession> panelSession;
1460 if (panelVec.size() > 1) {
1461 TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1462 return;
1463 } else if (panelVec.size() == 1) {
1464 panelSession = panelVec.front();
1465 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1466 } else {
1467 SessionInfo panelInfo = {
1468 .bundleName_ = "SCBKeyboardPanel",
1469 .moduleName_ = "SCBKeyboardPanel",
1470 .abilityName_ = "SCBKeyboardPanel",
1471 .isSystem_ = true,
1472 .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1473 .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1474 .screenId_ = static_cast<uint64_t>(displayId),
1475 .isRotable_ = true,
1476 };
1477 if (systemConfig_.IsPcWindow()) {
1478 panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1479 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1480 } else {
1481 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1482 }
1483 panelSession = RequestSceneSession(panelInfo, nullptr);
1484 if (panelSession == nullptr) {
1485 TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1486 return;
1487 }
1488 }
1489 keyboardSession->BindKeyboardPanelSession(panelSession);
1490 panelSession->BindKeyboardSession(keyboardSession);
1491 TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1492 panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1493 }
1494
CreateSceneSession(const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property)1495 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1496 sptr<WindowSessionProperty> property)
1497 {
1498 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1499 sptr<SceneSession> sceneSession = nullptr;
1500 if (sessionInfo.isSystem_) {
1501 sceneSession = new SCBSystemSession(sessionInfo, specificCb);
1502 WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1503 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1504 sceneSession = new MainSession(sessionInfo, specificCb);
1505 TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1506 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1507 sceneSession = new SubSession(sessionInfo, specificCb);
1508 TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1509 } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1510 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1511 sceneSession = new KeyboardSession(sessionInfo, specificCb, keyboardCb);
1512 CreateKeyboardPanelSession(sceneSession);
1513 TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1514 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1515 sceneSession = new SystemSession(sessionInfo, specificCb);
1516 TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1517 } else {
1518 TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1519 }
1520 if (sceneSession != nullptr) {
1521 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1522 sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1523 sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1524 return this->GetAppForceLandscapeConfig(bundleName);
1525 });
1526 sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1527 this->UpdatePrivateStateAndNotify(persistentId);
1528 });
1529 sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1530 this->NotifyVisibleChange(persistentId);
1531 });
1532 if (sceneSession->moveDragController_) {
1533 sceneSession->moveDragController_->SetIsPcWindow(systemConfig_.IsPcWindow());
1534 }
1535 }
1536 return sceneSession;
1537 }
1538
RequestSceneSession(const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property)1539 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1540 sptr<WindowSessionProperty> property)
1541 {
1542 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1543 auto session = GetSceneSession(sessionInfo.persistentId_);
1544 if (session != nullptr) {
1545 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1546 TLOGD(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1547 return session;
1548 }
1549 if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1550 TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1551 "abilityName: %{public}s, appIndex: %{public}d",
1552 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1553 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1554 SessionIdentityInfo identityInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_,
1555 sessionInfo.abilityName_, sessionInfo.appIndex_, sessionInfo.appInstanceKey_,
1556 sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1557 auto sceneSession = GetSceneSessionByIdentityInfo(identityInfo);
1558 bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1559 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1560 if (isSingleStart) {
1561 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1562 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1563 sessionInfo.persistentId_);
1564 return sceneSession;
1565 }
1566 }
1567 }
1568
1569 const char* const where = __func__;
1570 auto task = [this, sessionInfo, property, where] {
1571 TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession, appName: [%{public}s %{public}s %{public}s]"
1572 "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1573 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1574 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1575 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1576 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1577 if (sceneSession == nullptr) {
1578 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1579 return sceneSession;
1580 }
1581 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
1582 WindowHelper::IsMainWindow(sceneSession->GetWindowType()) &&
1583 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
1584 MultiInstanceManager::GetInstance().FillInstanceKeyIfNeed(sceneSession);
1585 }
1586 InitSceneSession(sceneSession, sessionInfo, property);
1587 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1588 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1589 where, sceneSession->GetSessionInfo().ancoSceneState);
1590 bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1591 const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1592 if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1593 TLOGNI(WmsLogTag::WMS_LIFE,
1594 "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1595 where, reusedSceneSession->GetPersistentId(),
1596 reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1597 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1598 return reusedSceneSession;
1599 }
1600 if (isPreHandleSuccess) {
1601 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1602 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1603 }
1604 }
1605 {
1606 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1607 sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1608 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
1609 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
1610 MultiInstanceManager::GetInstance().IncreaseInstanceKeyRefCount(sceneSession);
1611 }
1612 }
1613 PerformRegisterInRequestSceneSession(sceneSession);
1614 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1615 TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession id: %{public}d, type: %{public}d",
1616 sceneSession->GetPersistentId(), sceneSession->GetWindowType());
1617 return sceneSession;
1618 };
1619 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1620 }
1621
InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo, const sptr<WindowSessionProperty>& property)1622 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1623 const sptr<WindowSessionProperty>& property)
1624 {
1625 auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1626 DisplayId curDisplayId = DISPLAY_ID_INVALID;
1627 if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1628 curDisplayId = sessionInfo.screenId_;
1629 } else if (callerSession) {
1630 auto callerSessionProperty = callerSession->GetSessionProperty();
1631 if (callerSessionProperty) {
1632 curDisplayId = callerSessionProperty->GetDisplayId();
1633 }
1634 }
1635 auto sessionProperty = sceneSession->GetSessionProperty();
1636 if (sessionProperty) {
1637 sessionProperty->SetDisplayId(curDisplayId);
1638 sceneSession->SetScreenId(curDisplayId);
1639 TLOGD(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
1640 curDisplayId);
1641 }
1642 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
1643 sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
1644 if (sessionInfo.isSystem_) {
1645 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1646 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1647 auto rootContext = rootSceneContextWeak_.lock();
1648 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1649 } else {
1650 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
1651 "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
1652 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1653 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1654 }
1655 RegisterSessionExceptionFunc(sceneSession);
1656 RegisterVisibilityChangedDetectFunc(sceneSession);
1657 // Skip FillSessionInfo when atomicService free-install start.
1658 if (!IsAtomicServiceFreeInstall(sessionInfo)) {
1659 FillSessionInfo(sceneSession);
1660 }
1661 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
1662 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1663 WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
1664 }
1665 if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
1666 sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
1667 }
1668 sceneSession->SetSystemConfig(systemConfig_);
1669 sceneSession->SetSnapshotScale(snapshotScale_);
1670 UpdateParentSessionForDialog(sceneSession, property);
1671 }
1672
NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)1673 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1674 {
1675 auto task = [abilityName = sessionInfo.abilityName_,
1676 bundleName = sessionInfo.bundleName_, toScreenId = sessionInfo.screenId_, action, fromScreenId] {
1677 sptr<DisplayChangeInfo> info = sptr<DisplayChangeInfo>::MakeSptr();
1678 info->action_ = action;
1679 info->abilityName_ = std::move(abilityName);
1680 info->bundleName_ = std::move(bundleName);
1681 info->toScreenId_ = toScreenId;
1682 info->fromScreenId_ = fromScreenId;
1683 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1684 TLOGNI(WmsLogTag::DMS, "Notify ability %{public}s bundle %{public}s update toScreen id: %{public}" PRIu64 ".",
1685 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1686 };
1687 taskScheduler_->PostAsyncTask(task, __func__);
1688 }
1689
PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)1690 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1691 {
1692 RegisterSessionSnapshotFunc(sceneSession);
1693 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1694 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1695 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1696 RegisterGetStateFromManagerFunc(sceneSession);
1697 RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
1698 RegisterAcquireRotateAnimationConfigFunc(sceneSession);
1699 }
1700
UpdateSceneSessionWant(const SessionInfo& sessionInfo)1701 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1702 {
1703 if (sessionInfo.persistentId_ != 0) {
1704 auto session = GetSceneSession(sessionInfo.persistentId_);
1705 if (session != nullptr && sessionInfo.want != nullptr) {
1706 TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
1707 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1708 session->SetSessionInfoWant(sessionInfo.want);
1709 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
1710 } else {
1711 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1712 }
1713 } else {
1714 TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
1715 session == nullptr, sessionInfo.persistentId_);
1716 }
1717 } else {
1718 TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
1719 }
1720 }
1721
UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)1722 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
1723 {
1724 if (session != nullptr) {
1725 if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1726 FillSessionInfo(session);
1727 if (CheckCollaboratorType(session->GetCollaboratorType())) {
1728 PreHandleCollaborator(session, persistentId);
1729 }
1730 }
1731 }
1732 }
1733
SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)1734 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
1735 {
1736 sptr<AAFwk::SessionInfo> abilitySessionInfo = sptr<AAFwk::SessionInfo>::MakeSptr();
1737 auto sessionInfo = scnSession->GetSessionInfo();
1738 sptr<ISession> iSession(scnSession);
1739 abilitySessionInfo->sessionToken = iSession->AsObject();
1740 abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
1741 std::chrono::system_clock::now()).time_since_epoch().count());
1742 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
1743 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
1744 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
1745 abilitySessionInfo->persistentId = scnSession->GetPersistentId();
1746 abilitySessionInfo->requestCode = sessionInfo.requestCode;
1747 abilitySessionInfo->resultCode = sessionInfo.resultCode;
1748 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
1749 abilitySessionInfo->startSetting = sessionInfo.startSetting;
1750 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
1751 abilitySessionInfo->userId = currentUserId_;
1752 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
1753 abilitySessionInfo->processOptions = sessionInfo.processOptions;
1754 if (sessionInfo.want != nullptr) {
1755 abilitySessionInfo->want = *sessionInfo.want;
1756 } else {
1757 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
1758 sessionInfo.moduleName_);
1759 }
1760 int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
1761 bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
1762 if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
1763 TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
1764 appIndex, sessionInfo.appIndex_);
1765 }
1766 if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
1767 TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
1768 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
1769 }
1770 auto sessionProperty = scnSession->GetSessionProperty();
1771 if (sessionProperty) {
1772 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
1773 static_cast<int>(sessionProperty->GetDisplayId()));
1774 }
1775 abilitySessionInfo->instanceKey = sessionInfo.appInstanceKey_;
1776 return abilitySessionInfo;
1777 }
1778
PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)1779 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
1780 {
1781 auto task = [this, persistentId, &isPrepareTerminate]() {
1782 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
1783 isPrepareTerminate = false;
1784 WLOGE("not support prepareTerminate, Id:%{public}d", persistentId);
1785 return WSError::WS_OK;
1786 }
1787 auto scnSession = GetSceneSession(persistentId);
1788 if (scnSession == nullptr) {
1789 WLOGFE("PrepareTerminate scnSession is null, Id:%{public}d", persistentId);
1790 isPrepareTerminate = false;
1791 return WSError::WS_ERROR_NULLPTR;
1792 }
1793 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1794 if (scnSessionInfo == nullptr) {
1795 WLOGFE("PrepareTerminate scnSessionInfo is null, Id:%{public}d", persistentId);
1796 isPrepareTerminate = false;
1797 return WSError::WS_ERROR_NULLPTR;
1798 }
1799 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
1800 PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
1801 TLOGI(WmsLogTag::WMS_MAIN, "PrepareTerminateAbilityBySCB Id:%{public}d isPrepareTerminate:%{public}d "
1802 "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
1803 return WSError::WS_OK;
1804 };
1805 taskScheduler_->PostSyncTask(task, "PrepareTerminate:PID:" + std::to_string(persistentId));
1806 return WSError::WS_OK;
1807 }
1808
RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)1809 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
1810 {
1811 wptr<SceneSession> weakSceneSession(sceneSession);
1812 auto task = [this, weakSceneSession, isNewActive]() {
1813 sptr<SceneSession> scnSession = weakSceneSession.promote();
1814 if (scnSession == nullptr) {
1815 TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
1816 return WSError::WS_ERROR_NULLPTR;
1817 }
1818 auto persistentId = scnSession->GetPersistentId();
1819 if (!Session::IsScbCoreEnabled()) {
1820 scnSession->SetForegroundInteractiveStatus(true);
1821 }
1822 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
1823 TLOGI(WmsLogTag::WMS_MAIN, "Request active id:%{public}d system:%{public}u isNewActive:%{public}d",
1824 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_), isNewActive);
1825 if (!GetSceneSession(persistentId)) {
1826 TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
1827 return WSError::WS_ERROR_INVALID_SESSION;
1828 }
1829 auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
1830 if (ret == WSError::WS_OK) {
1831 scnSession->SetExitSplitOnBackground(false);
1832 }
1833 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
1834 abilityInfoMap_.clear(); // clear cache after terminate
1835 return ret;
1836 };
1837 std::string taskName = "RequestSceneSessionActivation:PID:" +
1838 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
1839 taskScheduler_->PostAsyncTask(task, taskName);
1840 return WSError::WS_OK;
1841 }
1842
IsKeyboardForeground()1843 bool SceneSessionManager::IsKeyboardForeground()
1844 {
1845 bool isKeyboardForeground = false;
1846 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1847 for (const auto &item : sceneSessionMap_) {
1848 auto sceneSession = item.second;
1849 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1850 isKeyboardForeground = sceneSession->IsSessionForeground();
1851 break;
1852 }
1853 }
1854
1855 return isKeyboardForeground;
1856 }
1857
RequestInputMethodCloseKeyboard(const int32_t persistentId)1858 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
1859 {
1860 auto sceneSession = GetSceneSession(persistentId);
1861 if (sceneSession == nullptr) {
1862 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
1863 return;
1864 }
1865 // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
1866 if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
1867 !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
1868 TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
1869 persistentId, sceneSession->GetSessionState());
1870 sceneSession->RequestHideKeyboard(true);
1871 }
1872 }
1873
StartUIAbilityBySCB(sptr<SceneSession>& scnSession)1874 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
1875 {
1876 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1877 if (abilitySessionInfo == nullptr) {
1878 return ERR_NULL_OBJECT;
1879 }
1880 return StartUIAbilityBySCB(abilitySessionInfo);
1881 }
1882
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)1883 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
1884 {
1885 bool isColdStart = false;
1886 return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
1887 }
1888
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)1889 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
1890 {
1891 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
1892 if (abilitySessionInfo == nullptr) {
1893 return ERR_NULL_OBJECT;
1894 }
1895 return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
1896 }
1897
RequestSceneSessionActivationInner( sptr<SceneSession>& scnSession, bool isNewActive)1898 WSError SceneSessionManager::RequestSceneSessionActivationInner(
1899 sptr<SceneSession>& scnSession, bool isNewActive)
1900 {
1901 auto persistentId = scnSession->GetPersistentId();
1902 RequestInputMethodCloseKeyboard(persistentId);
1903 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1904 scnSession->SetIsStarting(true);
1905 }
1906 if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
1907 if (Session::IsScbCoreEnabled()) {
1908 if (scnSession->IsVisibleForeground()) {
1909 RequestSessionFocusImmediately(persistentId);
1910 } else {
1911 PostProcessFocusState state = { true, true, true, FocusChangeReason::SCB_START_APP };
1912 scnSession->SetPostProcessFocusState(state);
1913 }
1914 } else {
1915 RequestSessionFocusImmediately(persistentId);
1916 }
1917 }
1918 if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1919 FillSessionInfo(scnSession);
1920 if (!PreHandleCollaborator(scnSession, persistentId)) {
1921 TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
1922 persistentId, scnSession->GetSessionInfo().ancoSceneState);
1923 scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
1924 return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
1925 }
1926 }
1927 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1928 if (!scnSessionInfo) {
1929 TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
1930 return WSError::WS_ERROR_NULLPTR;
1931 }
1932 scnSession->NotifyActivation();
1933 scnSessionInfo->isNewWant = isNewActive;
1934 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1935 scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
1936 scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
1937 }
1938 TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
1939 "module: %{public}s, uri: %{public}s, appIndex: %{public}d.", persistentId,
1940 scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
1941 scnSessionInfo->want.GetElement().GetBundleName().c_str(),
1942 scnSessionInfo->want.GetElement().GetModuleName().c_str(),
1943 scnSessionInfo->want.GetElement().GetURI().c_str(),
1944 scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0));
1945 int32_t errCode = ERR_OK;
1946 bool isColdStart = false;
1947 bool isAppSupportPhoneInPc = false;
1948 auto sessionProperty = scnSession->GetSessionProperty();
1949 if (sessionProperty != nullptr) {
1950 isAppSupportPhoneInPc = sessionProperty->GetIsAppSupportPhoneInPc();
1951 }
1952 if (systemConfig_.backgroundswitch == false || isAppSupportPhoneInPc) {
1953 TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
1954 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1955 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1956 } else {
1957 TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
1958 isNewActive, scnSession->GetSessionState());
1959 if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
1960 scnSession->GetSessionState() == SessionState::STATE_END) {
1961 TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
1962 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1963 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
1964 } else {
1965 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
1966 scnSession->NotifySessionForeground(1, true);
1967 }
1968 }
1969 auto sessionInfo = scnSession->GetSessionInfo();
1970 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1971 WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
1972 }
1973 NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
1974
1975 if (errCode != ERR_OK) {
1976 TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
1977 scnSession->NotifySessionExceptionInner(scnSessionInfo, true);
1978 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
1979 startUIAbilityErrorFunc_(
1980 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
1981 }
1982 }
1983 if (isColdStart) {
1984 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
1985 scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
1986 scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
1987 scnSession->ResetSessionConnectState();
1988 scnSession->ResetIsActive();
1989 }
1990 return WSError::WS_OK;
1991 }
1992
NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession, sptr<AAFwk::SessionInfo>& scnSessionInfo)1993 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
1994 sptr<AAFwk::SessionInfo>& scnSessionInfo)
1995 {
1996 if (scnSession == nullptr || scnSessionInfo == nullptr) {
1997 return;
1998 }
1999 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2000 NotifyLoadAbility(scnSession->GetCollaboratorType(),
2001 scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
2002 NotifyUpdateSessionInfo(scnSession);
2003 NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2004 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2005 }
2006 }
2007
IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)2008 bool SceneSessionManager::IsPcSceneSessionLifecycle(const sptr<SceneSession>& sceneSession)
2009 {
2010 bool isPcAppInPad = false;
2011 bool isAppSupportPhoneInPc = false;
2012 auto property = sceneSession->GetSessionProperty();
2013 if (property) {
2014 isPcAppInPad = property->GetIsPcAppInPad();
2015 isAppSupportPhoneInPc = property->GetIsAppSupportPhoneInPc();
2016 }
2017 return (systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || isPcAppInPad;
2018 }
2019
RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession, const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)2020 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2021 const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2022 {
2023 wptr<SceneSession> weakSceneSession(sceneSession);
2024 auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
2025 auto scnSession = weakSceneSession.promote();
2026 if (scnSession == nullptr) {
2027 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
2028 return WSError::WS_ERROR_NULLPTR;
2029 }
2030 auto persistentId = scnSession->GetPersistentId();
2031 TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2032 "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2033 persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2034 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2035 scnSession->SetActive(false);
2036
2037 if (isToDesktop) {
2038 auto info = scnSession->GetSessionInfo();
2039 info.callerToken_ = nullptr;
2040 info.callingTokenId_ = 0;
2041 scnSession->SetSessionInfo(info);
2042 }
2043
2044 scnSession->BackgroundTask(isSaveSnapshot);
2045 if (!GetSceneSession(persistentId)) {
2046 TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2047 return WSError::WS_ERROR_INVALID_SESSION;
2048 }
2049 if (persistentId == brightnessSessionId_) {
2050 UpdateBrightness(focusedSessionId_);
2051 }
2052 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2053 if (!scnSessionInfo) {
2054 TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2055 return WSError::WS_ERROR_NULLPTR;
2056 }
2057 if (IsPcSceneSessionLifecycle(scnSession)) {
2058 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2059 scnSession->NotifySessionBackground(1, true, true);
2060 } else {
2061 TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2062 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2063 if (!isDelegator) {
2064 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2065 } else {
2066 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2067 }
2068 }
2069
2070 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2071 auto sessionInfo = scnSession->GetSessionInfo();
2072 WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2073 }
2074 return WSError::WS_OK;
2075 };
2076 std::string taskName = "RequestSceneSessionBackground:PID:" +
2077 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2078 taskScheduler_->PostAsyncTask(task, taskName);
2079 return WSError::WS_OK;
2080 }
2081
NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)2082 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2083 {
2084 wptr<SceneSession> weakSceneSession(sceneSession);
2085 auto task = [this, weakSceneSession, interactive]() {
2086 auto scnSession = weakSceneSession.promote();
2087 if (scnSession == nullptr) {
2088 WLOGFE("session is nullptr");
2089 return;
2090 }
2091 auto persistentId = scnSession->GetPersistentId();
2092 WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2093 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2094 if (!GetSceneSession(persistentId)) {
2095 WLOGFE("session is invalid with %{public}d", persistentId);
2096 return;
2097 }
2098 scnSession->NotifyForegroundInteractiveStatus(interactive);
2099 };
2100
2101 taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2102 }
2103
DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)2104 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2105 {
2106 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2107 if (scnSession == nullptr) {
2108 TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2109 return WSError::WS_ERROR_NULLPTR;
2110 }
2111 if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2112 TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2113 auto dialogVec = scnSession->GetDialogVector();
2114 for (auto dialog : dialogVec) {
2115 if (dialog == nullptr) {
2116 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2117 continue;
2118 }
2119 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2120 if (sceneSession == nullptr) {
2121 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2122 return WSError::WS_ERROR_INVALID_SESSION;
2123 }
2124 WindowDestroyNotifyVisibility(sceneSession);
2125 dialog->NotifyDestroy();
2126 dialog->Disconnect();
2127
2128 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2129 if (dialogSceneSession != nullptr) {
2130 dialogSceneSession->ClearSpecificSessionCbMap();
2131 }
2132 {
2133 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2134 EraseSceneSessionAndMarkDirtyLockFree(dialog->GetPersistentId());
2135 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2136 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2137 }
2138 }
2139 scnSession->ClearDialogVector();
2140 return WSError::WS_OK;
2141 }
2142 return WSError::WS_ERROR_INVALID_SESSION;
2143 }
2144
DestroySubSession(const sptr<SceneSession>& sceneSession)2145 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2146 {
2147 if (sceneSession == nullptr) {
2148 WLOGFW("sceneSession is nullptr");
2149 return;
2150 }
2151 for (const auto& elem : sceneSession->GetSubSession()) {
2152 if (elem != nullptr) {
2153 const auto& persistentId = elem->GetPersistentId();
2154 TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2155 DestroyAndDisconnectSpecificSessionInner(persistentId);
2156 }
2157 }
2158 }
2159
DestroyToastSession(const sptr<SceneSession>& sceneSession)2160 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2161 {
2162 if (sceneSession == nullptr) {
2163 TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2164 return;
2165 }
2166 for (const auto& elem : sceneSession->GetToastSession()) {
2167 if (elem != nullptr) {
2168 const auto& persistentId = elem->GetPersistentId();
2169 TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2170 DestroyAndDisconnectSpecificSessionInner(persistentId);
2171 }
2172 }
2173 }
2174
EraseSceneSessionMapById(int32_t persistentId)2175 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2176 {
2177 auto sceneSession = GetSceneSession(persistentId);
2178 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2179 EraseSceneSessionAndMarkDirtyLockFree(persistentId);
2180 systemTopSceneSessionMap_.erase(persistentId);
2181 nonSystemFloatSceneSessionMap_.erase(persistentId);
2182 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_) &&
2183 MultiInstanceManager::GetInstance().IsMultiInstance(sceneSession->GetSessionInfo().bundleName_)) {
2184 MultiInstanceManager::GetInstance().DecreaseInstanceKeyRefCount(sceneSession);
2185 }
2186 }
2187
2188 /**
2189 * if visible session is erased, mark dirty
2190 * lock-free
2191 */
EraseSceneSessionAndMarkDirtyLockFree(int32_t persistentId)2192 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLockFree(int32_t persistentId)
2193 {
2194 // get scene session lock-free
2195 auto iter = sceneSessionMap_.find(persistentId);
2196 if (iter == sceneSessionMap_.end()) {
2197 TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2198 return;
2199 }
2200 sptr<SceneSession> sceneSession = iter->second;
2201
2202 if (sceneSession != nullptr && sceneSession->IsVisible()) {
2203 sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2204 }
2205 sceneSessionMap_.erase(persistentId);
2206 }
2207
RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession, bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)2208 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2209 bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2210 {
2211 auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2212 needRemoveSession, isSaveSnapshot, isForceClean]() {
2213 auto scnSession = weakSceneSession.promote();
2214 if (scnSession == nullptr) {
2215 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2216 return WSError::WS_ERROR_NULLPTR;
2217 }
2218 auto persistentId = scnSession->GetPersistentId();
2219 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2220 RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2221 lastUpdatedAvoidArea_.erase(persistentId);
2222 DestroyDialogWithMainWindow(scnSession);
2223 DestroyToastSession(scnSession);
2224 DestroySubSession(scnSession); // destroy sub session by destruction
2225 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2226 " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2227 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2228 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2229 auto sessionInfo = scnSession->GetSessionInfo();
2230 WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sessionInfo.bundleName_);
2231 }
2232 WindowDestroyNotifyVisibility(scnSession);
2233 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2234 scnSession->DisconnectTask(false, isSaveSnapshot);
2235 if (!GetSceneSession(persistentId)) {
2236 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2237 return WSError::WS_ERROR_INVALID_SESSION;
2238 }
2239 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2240 if (!scnSessionInfo) {
2241 return WSError::WS_ERROR_NULLPTR;
2242 }
2243 scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2244 if (scnSessionInfo->resultCode == -1) {
2245 OHOS::AAFwk::Want want;
2246 scnSessionInfo->want = want;
2247 }
2248 return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2249 };
2250 std::string taskName = "RequestSceneSessionDestruction:PID:" +
2251 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2252 taskScheduler_->PostAsyncTask(task, taskName);
2253 return WSError::WS_OK;
2254 }
2255
ResetWantInfo(const sptr<SceneSession>& sceneSession)2256 void SceneSessionManager::ResetWantInfo(const sptr<SceneSession>& sceneSession)
2257 {
2258 auto& sessionInfo = sceneSession->GetSessionInfo();
2259 if (sessionInfo.want != nullptr) {
2260 const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2261 const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2262 const auto& keySessionId = sessionInfo.want->GetStringParam(KEY_SESSION_ID);
2263 auto want = std::make_shared<AAFwk::Want>();
2264 AppExecFwk::ElementName element;
2265 element.SetBundleName(bundleName);
2266 element.SetAbilityName(abilityName);
2267 want->SetElement(element);
2268 want->SetBundle(bundleName);
2269 if (!keySessionId.empty()) {
2270 want->SetParam(KEY_SESSION_ID, keySessionId);
2271 }
2272 sceneSession->SetSessionInfoWant(want);
2273 }
2274 }
2275
RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession, sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)2276 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& sceneSession,
2277 sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2278 {
2279 auto persistentId = sceneSession->GetPersistentId();
2280 TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}d",
2281 persistentId, sceneSession->GetSessionInfo().isSystem_);
2282 if (isForceClean) {
2283 AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2284 } else {
2285 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2286 }
2287 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2288 if (needRemoveSession) {
2289 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2290 NotifyClearSession(sceneSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2291 }
2292 EraseSceneSessionMapById(persistentId);
2293 } else {
2294 // if terminate, reset want. so start from recent, start a new one.
2295 TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2296 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
2297 sceneSession->SetSessionInfoWant(nullptr);
2298 }
2299 ResetWantInfo(sceneSession);
2300 sceneSession->ResetSessionInfoResultCode();
2301 }
2302 NotifySessionForCallback(sceneSession, needRemoveSession);
2303 // Arrive at the STOP task end.
2304 sceneSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2305 // Clear js cb map if needed.
2306 sceneSession->ClearJsSceneSessionCbMap(needRemoveSession);
2307 return WSError::WS_OK;
2308 }
2309
AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage, const sptr<SceneSession>& sceneSession)2310 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2311 const sptr<SceneSession>& sceneSession)
2312 {
2313 if (sceneSession == nullptr || sessionStage == nullptr) {
2314 TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2315 return;
2316 }
2317
2318 auto remoteObject = sessionStage->AsObject();
2319 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2320 if (windowDeath_ == nullptr) {
2321 TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2322 return;
2323 }
2324 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2325 TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2326 return;
2327 }
2328 WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2329 }
2330
DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)2331 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2332 {
2333 auto task = [this, remoteObject]() {
2334 auto iter = remoteObjectMap_.find(remoteObject);
2335 if (iter == remoteObjectMap_.end()) {
2336 WLOGFE("Invalid remoteObject");
2337 return;
2338 }
2339 WLOGFD("Remote died, id: %{public}d", iter->second);
2340 auto sceneSession = GetSceneSession(iter->second);
2341 if (sceneSession == nullptr) {
2342 WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2343 return;
2344 }
2345 DestroyAndDisconnectSpecificSessionInner(iter->second);
2346 remoteObjectMap_.erase(iter);
2347 };
2348 taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2349 }
2350
CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session, SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)2351 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2352 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2353 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2354 SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2355 {
2356 if (property == nullptr) {
2357 WLOGFE("property is nullptr");
2358 return WSError::WS_ERROR_NULLPTR;
2359 }
2360
2361 if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2362 WLOGFE("create system window or modal subwindow permission denied!");
2363 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2364 }
2365
2366 bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2367 property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2368 bool isSystemCalling = SessionPermission::IsSystemCalling();
2369 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2370 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2371 if (parentSession) {
2372 shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2373 }
2374 }
2375 if (shouldBlock) {
2376 TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2377 return WSError::WS_ERROR_INVALID_OPERATION;
2378 }
2379
2380 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2381 property->GetIsUIExtFirstSubWindow() && property->GetIsUIExtensionAbilityProcess() &&
2382 SessionPermission::IsStartedByUIExtension()) {
2383 auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2384 if (extensionParentSession == nullptr) {
2385 WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2386 return WSError::WS_ERROR_NULLPTR;
2387 }
2388 SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2389 AAFwk::UIExtensionHostInfo hostInfo;
2390 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2391 if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2392 WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2393 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2394 hostInfo.elementName_.GetBundleName().c_str());
2395 return WSError::WS_ERROR_INVALID_WINDOW;
2396 }
2397 }
2398
2399 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2400 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2401 WLOGFE("The alarm window has been deprecated!");
2402 return WSError::WS_ERROR_INVALID_WINDOW;
2403 }
2404
2405 if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2406 WLOGFE("pip window is not enable to create.");
2407 return WSError::WS_DO_NOTHING;
2408 }
2409 TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2410 property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2411
2412 // Get pid and uid before posting task.
2413 auto pid = IPCSkeleton::GetCallingRealPid();
2414 auto uid = IPCSkeleton::GetCallingUid();
2415 auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2416 &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2417 if (property == nullptr) {
2418 return WSError::WS_ERROR_NULLPTR;
2419 }
2420 const auto& type = property->GetWindowType();
2421 // create specific session
2422 SessionInfo info;
2423 info.windowType_ = static_cast<uint32_t>(type);
2424 info.bundleName_ = property->GetSessionInfo().bundleName_;
2425 info.abilityName_ = property->GetSessionInfo().abilityName_;
2426 info.moduleName_ = property->GetSessionInfo().moduleName_;
2427
2428 ClosePipWindowIfExist(type);
2429 sptr<SceneSession> newSession = RequestSceneSession(info, property);
2430 if (newSession == nullptr) {
2431 TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2432 return WSError::WS_ERROR_NULLPTR;
2433 }
2434 property->SetSystemCalling(isSystemCalling);
2435 auto errCode = newSession->ConnectInner(
2436 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2437 newSession->SetIsSystemSpecificSession(isSystemCalling);
2438 systemConfig = systemConfig_;
2439 if (property) {
2440 persistentId = property->GetPersistentId();
2441 }
2442
2443 NotifyCreateSpecificSession(newSession, property, type);
2444 session = newSession;
2445 AddClientDeathRecipient(sessionStage, newSession);
2446 TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2447 "parentId: %{public}d, type: %{public}d",
2448 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2449 return errCode;
2450 };
2451
2452 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2453 }
2454
ClosePipWindowIfExist(WindowType type)2455 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2456 {
2457 if (type != WindowType::WINDOW_TYPE_PIP) {
2458 return;
2459 }
2460 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2461 for (const auto& iter: sceneSessionMap_) {
2462 auto& session = iter.second;
2463 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2464 session->NotifyCloseExistPipWindow();
2465 break;
2466 }
2467 }
2468 }
2469
CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)2470 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2471 {
2472 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2473 for (const auto& iter: sceneSessionMap_) {
2474 auto& session = iter.second;
2475 if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2476 pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2477 IsSessionVisibleForeground(session)) {
2478 TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2479 return false;
2480 }
2481 }
2482 return true;
2483 }
2484
isEnablePiPCreate(const sptr<WindowSessionProperty>& property)2485 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2486 {
2487 if (isScreenLocked_) {
2488 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2489 return false;
2490 }
2491 Rect pipRect = property->GetRequestRect();
2492 if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2493 TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2494 return false;
2495 }
2496 if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2497 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2498 return false;
2499 }
2500 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2501 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2502 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2503 return false;
2504 }
2505 return true;
2506 }
2507
CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)2508 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2509 {
2510 WindowType type = property->GetWindowType();
2511 if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
2512 return true;
2513 }
2514
2515 if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
2516 TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
2517 return false;
2518 }
2519
2520 if (!SessionPermission::IsSystemCalling()) {
2521 TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
2522 return false;
2523 }
2524
2525 return true;
2526 }
2527
CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)2528 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
2529 {
2530 WindowType type = property->GetWindowType();
2531 if (WindowHelper::IsUIExtensionWindow(type)) {
2532 // UIExtension window disallowed.
2533 return false;
2534 }
2535 if (!WindowHelper::IsSystemWindow(type)) {
2536 // type is not system
2537 return true;
2538 }
2539 if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) {
2540 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
2541 if (SessionPermission::IsStartedByInputMethod()) {
2542 TLOGD(WmsLogTag::WMS_KEYBOARD, "check permission success, input method app create input method window.");
2543 return true;
2544 } else {
2545 TLOGE(WmsLogTag::WMS_KEYBOARD, "check permission failed.");
2546 return false;
2547 }
2548 }
2549 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
2550 // some system types could be created by normal app
2551 return true;
2552 }
2553 if (type == WindowType::WINDOW_TYPE_FLOAT) {
2554 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
2555 if (SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW") &&
2556 (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd() ||
2557 systemConfig_.supportTypeFloatWindow_)) {
2558 WLOGFI("check float permission success.");
2559 return true;
2560 } else {
2561 WLOGFE("check float permission failed.");
2562 return false;
2563 }
2564 }
2565 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
2566 WLOGFD("check create permission success, create with system calling.");
2567 return true;
2568 }
2569 WLOGFE("check system window permission failed.");
2570 return false;
2571 }
2572
RecoverSessionInfo(const sptr<WindowSessionProperty>& property)2573 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
2574 {
2575 SessionInfo sessionInfo;
2576 if (property == nullptr) {
2577 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2578 return sessionInfo;
2579 }
2580 sessionInfo = property->GetSessionInfo();
2581 sessionInfo.persistentId_ = property->GetPersistentId();
2582 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
2583 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
2584 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
2585 sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
2586 ? SessionState::STATE_ACTIVE
2587 : SessionState::STATE_BACKGROUND;
2588 sessionInfo.isPersistentRecover_ = true;
2589 sessionInfo.appInstanceKey_ = property->GetAppInstanceKey();
2590 TLOGI(WmsLogTag::WMS_RECOVER,
2591 "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
2592 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
2593 "windowState=%{public}u, appInstanceKey=%{public}s",
2594 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2595 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_,
2596 sessionInfo.appInstanceKey_.c_str());
2597 return sessionInfo;
2598 }
2599
SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)2600 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
2601 {
2602 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
2603 "%{public}d", alivePersistentIds.size(), currentUserId_);
2604 alivePersistentIds_ = alivePersistentIds;
2605 }
2606
IsNeedRecover(const int32_t persistentId)2607 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
2608 {
2609 auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
2610 if (it == alivePersistentIds_.end()) {
2611 TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
2612 return false;
2613 }
2614 return true;
2615 }
2616
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property, bool isSpecificSession)2617 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
2618 bool isSpecificSession)
2619 {
2620 if (property == nullptr) {
2621 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2622 return WSError::WS_ERROR_NULLPTR;
2623 }
2624 if (!CheckSystemWindowPermission(property)) {
2625 TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
2626 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2627 }
2628 if (isSpecificSession) {
2629 if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
2630 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2631 return WSError::WS_ERROR_INVALID_PARAM;
2632 }
2633 } else {
2634 if (!IsNeedRecover(property->GetPersistentId())) {
2635 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2636 return WSError::WS_ERROR_INVALID_PARAM;
2637 }
2638 }
2639 return WSError::WS_OK;
2640 }
2641
RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)2642 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2643 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2644 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
2645 {
2646 auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
2647 if (propCheckRet != WSError::WS_OK) {
2648 return propCheckRet;
2649 }
2650 auto pid = IPCSkeleton::GetCallingRealPid();
2651 auto uid = IPCSkeleton::GetCallingUid();
2652 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
2653 if (recoveringFinished_) {
2654 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2655 return WSError::WS_ERROR_INVALID_OPERATION;
2656 }
2657 // recover specific session
2658 SessionInfo info = RecoverSessionInfo(property);
2659 TLOGI(WmsLogTag::WMS_RECOVER, "callingSessionId = %{public}" PRIu32, property->GetCallingSessionId());
2660 ClosePipWindowIfExist(property->GetWindowType());
2661 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
2662 if (sceneSession == nullptr) {
2663 TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
2664 return WSError::WS_ERROR_NULLPTR;
2665 }
2666
2667 auto persistentId = sceneSession->GetPersistentId();
2668 if (persistentId != info.persistentId_) {
2669 TLOGE(WmsLogTag::WMS_RECOVER,
2670 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
2671 info.persistentId_, persistentId, property->GetParentPersistentId());
2672 failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
2673 EraseSceneSessionMapById(persistentId);
2674 return WSError::WS_ERROR_INVALID_SESSION;
2675 }
2676
2677 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2678 if (errCode != WSError::WS_OK) {
2679 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
2680 EraseSceneSessionMapById(persistentId);
2681 return errCode;
2682 }
2683 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
2684 CacheSubSessionForRecovering(sceneSession, property);
2685 NotifySessionUnfocusedToClient(persistentId);
2686 AddClientDeathRecipient(sessionStage, sceneSession);
2687 session = sceneSession;
2688 return errCode;
2689 };
2690 return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
2691 }
2692
NotifyRecoveringFinished()2693 void SceneSessionManager::NotifyRecoveringFinished()
2694 {
2695 taskScheduler_->PostAsyncTask([this]() {
2696 TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
2697 recoveringFinished_ = true;
2698 recoverSubSessionCacheMap_.clear();
2699 }, "NotifyRecoveringFinished");
2700 }
2701
CacheSubSessionForRecovering( sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)2702 void SceneSessionManager::CacheSubSessionForRecovering(
2703 sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
2704 {
2705 if (recoveringFinished_) {
2706 TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
2707 return;
2708 }
2709
2710 if (sceneSession == nullptr || property == nullptr) {
2711 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
2712 return;
2713 }
2714
2715 auto windowType = property->GetWindowType();
2716 if (!SessionHelper::IsSubWindow(windowType)) {
2717 return;
2718 }
2719
2720 auto persistentId = property->GetParentPersistentId();
2721 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
2722 return;
2723 }
2724
2725 TLOGI(WmsLogTag::WMS_RECOVER,
2726 "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
2727 sceneSession->GetPersistentId(), persistentId);
2728
2729 if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
2730 recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
2731 } else {
2732 recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
2733 }
2734 }
2735
RecoverCachedSubSession(int32_t persistentId)2736 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
2737 {
2738 auto iter = recoverSubSessionCacheMap_.find(persistentId);
2739 if (iter == recoverSubSessionCacheMap_.end()) {
2740 return;
2741 }
2742
2743 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
2744 for (auto& sceneSession : iter->second) {
2745 NotifyCreateSubSession(persistentId, sceneSession);
2746 }
2747 recoverSubSessionCacheMap_.erase(iter);
2748 }
2749
NotifySessionUnfocusedToClient(int32_t persistentId)2750 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
2751 {
2752 TLOGI(WmsLogTag::WMS_RECOVER, "Id=%{public}d", persistentId);
2753 listenerController_->NotifySessionUnfocused(persistentId);
2754 }
2755
RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)2756 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
2757 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2758 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
2759 {
2760 auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
2761 if (propCheckRet != WSError::WS_OK) {
2762 return propCheckRet;
2763 }
2764 auto pid = IPCSkeleton::GetCallingRealPid();
2765 auto uid = IPCSkeleton::GetCallingUid();
2766 auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
2767 if (recoveringFinished_) {
2768 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2769 return WSError::WS_ERROR_INVALID_OPERATION;
2770 }
2771 if (recoverSceneSessionFunc_ == nullptr) {
2772 TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
2773 return WSError::WS_ERROR_NULLPTR;
2774 }
2775 SessionInfo sessionInfo = RecoverSessionInfo(property);
2776 sptr<SceneSession> sceneSession = nullptr;
2777 if (SessionHelper::IsMainWindow(property->GetWindowType())) {
2778 sceneSession = RequestSceneSession(sessionInfo, nullptr);
2779 } else {
2780 sceneSession = RequestSceneSession(sessionInfo, property);
2781 }
2782 if (sceneSession == nullptr) {
2783 TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
2784 return WSError::WS_ERROR_NULLPTR;
2785 }
2786 int32_t persistentId = sceneSession->GetPersistentId();
2787 if (persistentId != sessionInfo.persistentId_) {
2788 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
2789 sessionInfo.persistentId_, persistentId);
2790 EraseSceneSessionMapById(persistentId);
2791 return WSError::WS_ERROR_INVALID_SESSION;
2792 }
2793 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2794 if (ret != WSError::WS_OK) {
2795 TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
2796 EraseSceneSessionMapById(sessionInfo.persistentId_);
2797 return ret;
2798 }
2799 sceneSession->SetRecovered(true);
2800 recoverSceneSessionFunc_(sceneSession, sessionInfo);
2801 NotifySessionUnfocusedToClient(persistentId);
2802 session = sceneSession;
2803 return WSError::WS_OK;
2804 };
2805 return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
2806 }
2807
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)2808 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
2809 {
2810 TLOGI(WmsLogTag::WMS_RECOVER, "called");
2811 recoverSceneSessionFunc_ = func;
2812 }
2813
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)2814 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
2815 {
2816 createSystemSessionFunc_ = func;
2817 }
2818
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)2819 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
2820 {
2821 createKeyboardSessionFunc_ = func;
2822 }
2823
RegisterCreateSubSessionListener(int32_t persistentId, const NotifyCreateSubSessionFunc& func)2824 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
2825 const NotifyCreateSubSessionFunc& func)
2826 {
2827 TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
2828 auto task = [this, persistentId, func]() {
2829 createSubSessionFuncMap_[persistentId] = func;
2830 RecoverCachedSubSession(persistentId);
2831 return WMError::WM_OK;
2832 };
2833 taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
2834 }
2835
NotifyCreateSpecificSession(sptr<SceneSession> newSession, sptr<WindowSessionProperty> property, const WindowType& type)2836 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
2837 sptr<WindowSessionProperty> property, const WindowType& type)
2838 {
2839 if (newSession == nullptr) {
2840 WLOGFE("newSession is nullptr");
2841 return;
2842 }
2843 if (property == nullptr) {
2844 WLOGFE("property is nullptr");
2845 return;
2846 }
2847 if (SessionHelper::IsSystemWindow(type)) {
2848 if (type == WindowType::WINDOW_TYPE_FLOAT) {
2849 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2850 if (parentSession != nullptr) {
2851 newSession->SetParentSession(parentSession);
2852 }
2853 }
2854 if (type == WindowType::WINDOW_TYPE_TOAST) {
2855 NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
2856 }
2857 if (type != WindowType::WINDOW_TYPE_DIALOG) {
2858 if (WindowHelper::IsSystemSubWindow(type)) {
2859 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2860 } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
2861 && createKeyboardSessionFunc_) {
2862 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
2863 } else if (createSystemSessionFunc_) {
2864 createSystemSessionFunc_(newSession);
2865 }
2866 TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
2867 newSession->GetPersistentId(), type);
2868 } else {
2869 TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, "
2870 "type:%{public}d", newSession->GetPersistentId(), type);
2871 return;
2872 }
2873 } else if (SessionHelper::IsSubWindow(type)) {
2874 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2875 TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
2876 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
2877 } else {
2878 TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
2879 newSession->GetPersistentId(), type);
2880 }
2881 }
2882
NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)2883 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
2884 {
2885 if (session == nullptr) {
2886 TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
2887 return;
2888 }
2889 auto iter = createSubSessionFuncMap_.find(persistentId);
2890 if (iter == createSubSessionFuncMap_.end()) {
2891 TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
2892 return;
2893 }
2894
2895 sptr<SceneSession> parentSession = nullptr;
2896 if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
2897 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2898 parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
2899 } else {
2900 parentSession = GetSceneSession(persistentId);
2901 }
2902 if (parentSession == nullptr) {
2903 TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
2904 persistentId, session->GetPersistentId());
2905 return;
2906 }
2907 parentSession->AddSubSession(session);
2908 session->SetParentSession(parentSession);
2909 if (iter->second) {
2910 iter->second(session);
2911 }
2912 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
2913 persistentId, session->GetPersistentId());
2914 }
2915
GetMainParentSceneSession(int32_t persistentId, const std::map<int32_t, sptr<SceneSession>>& sessionMap)2916 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
2917 const std::map<int32_t, sptr<SceneSession>>& sessionMap)
2918 {
2919 if (persistentId == INVALID_SESSION_ID) {
2920 TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
2921 return nullptr;
2922 }
2923 auto iter = sessionMap.find(persistentId);
2924 if (iter == sessionMap.end()) {
2925 WLOGFD("Error found scene session with id: %{public}d", persistentId);
2926 return nullptr;
2927 }
2928 sptr<SceneSession> parentSession = iter->second;
2929 if (parentSession == nullptr) {
2930 TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
2931 return nullptr;
2932 }
2933 bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
2934 parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
2935 if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
2936 TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
2937 return parentSession;
2938 }
2939 return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
2940 }
2941
NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)2942 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
2943 {
2944 if (session == nullptr) {
2945 TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
2946 return;
2947 }
2948
2949 auto parentSession = GetSceneSession(persistentId);
2950 if (parentSession == nullptr) {
2951 TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
2952 persistentId, session->GetPersistentId());
2953 return;
2954 }
2955 parentSession->AddToastSession(session);
2956 session->SetParentSession(parentSession);
2957 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
2958 persistentId, session->GetPersistentId());
2959 }
2960
UnregisterCreateSubSessionListener(int32_t persistentId)2961 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
2962 {
2963 TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
2964 auto task = [this, persistentId]() {
2965 auto iter = createSubSessionFuncMap_.find(persistentId);
2966 if (iter != createSubSessionFuncMap_.end()) {
2967 createSubSessionFuncMap_.erase(persistentId);
2968 } else {
2969 TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
2970 }
2971 return WMError::WM_OK;
2972 };
2973 taskScheduler_->PostSyncTask(task);
2974 }
2975
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)2976 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
2977 {
2978 WLOGFD("SetStatusBarEnabledChangeListener");
2979 if (!func) {
2980 WLOGFD("set func is null");
2981 }
2982 statusBarEnabledChangeFunc_ = func;
2983 }
2984
SetGestureNavigationEnabledChangeListener( const ProcessGestureNavigationEnabledChangeFunc& func)2985 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
2986 const ProcessGestureNavigationEnabledChangeFunc& func)
2987 {
2988 WLOGFD("SetGestureNavigationEnabledChangeListener");
2989 if (!func) {
2990 WLOGFD("set func is null");
2991 }
2992 gestureNavigationEnabledChangeFunc_ = func;
2993 }
2994
OnOutsideDownEvent(int32_t x, int32_t y)2995 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
2996 {
2997 TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
2998 if (outsideDownEventFunc_) {
2999 outsideDownEventFunc_(x, y);
3000 }
3001 }
3002
NotifySessionTouchOutside(int32_t persistentId)3003 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
3004 {
3005 auto task = [this, persistentId]() {
3006 int32_t callingSessionId = INVALID_WINDOW_ID;
3007 auto sceneSession = GetSceneSession(persistentId);
3008 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3009 callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
3010 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
3011 persistentId, callingSessionId);
3012 }
3013 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3014 for (const auto &item : sceneSessionMap_) {
3015 sceneSession = item.second;
3016 if (sceneSession == nullptr) {
3017 continue;
3018 }
3019 if (!(sceneSession->IsVisible() ||
3020 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3021 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
3022 continue;
3023 }
3024 auto sessionId = sceneSession->GetPersistentId();
3025 if ((!sceneSession->CheckOutTouchOutsideRegister()) &&
3026 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3027 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3028 continue;
3029 }
3030 if (sessionId == callingSessionId || sessionId == persistentId) {
3031 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3032 continue;
3033 }
3034 sceneSession->NotifyTouchOutside();
3035 }
3036 };
3037
3038 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3039 return;
3040 }
3041
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)3042 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3043 {
3044 WLOGFD("SetOutsideDownEventListener");
3045 outsideDownEventFunc_ = func;
3046 }
3047
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3048 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3049 {
3050 auto sceneSession = GetSceneSession(persistentId);
3051 if (sceneSession == nullptr) {
3052 return WSError::WS_ERROR_NULLPTR;
3053 }
3054 auto ret = sceneSession->UpdateActiveStatus(false);
3055 WindowDestroyNotifyVisibility(sceneSession);
3056 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
3057 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3058 if (parentSession == nullptr) {
3059 TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3060 } else {
3061 parentSession->RemoveDialogToParentSession(sceneSession);
3062 }
3063 }
3064 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_TOAST) {
3065 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3066 if (parentSession != nullptr) {
3067 TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3068 parentSession->RemoveToastSession(persistentId);
3069 } else {
3070 TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3071 }
3072 }
3073 ret = sceneSession->Disconnect();
3074 sceneSession->ClearSpecificSessionCbMap();
3075 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3076 DestroySubSession(sceneSession);
3077 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3078 if (parentSession != nullptr) {
3079 TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3080 parentSession->RemoveSubSession(persistentId);
3081 } else {
3082 TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3083 }
3084 DestroyUIServiceExtensionSubWindow(sceneSession);
3085 }
3086 {
3087 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3088 EraseSceneSessionAndMarkDirtyLockFree(persistentId);
3089 systemTopSceneSessionMap_.erase(persistentId);
3090 nonSystemFloatSceneSessionMap_.erase(persistentId);
3091 UnregisterCreateSubSessionListener(persistentId);
3092 }
3093 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3094 return ret;
3095 }
3096
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3097 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3098 {
3099 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3100 auto task = [this, persistentId, callingPid]() {
3101 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3102 auto sceneSession = GetSceneSession(persistentId);
3103 if (sceneSession == nullptr) {
3104 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3105 return WSError::WS_ERROR_NULLPTR;
3106 }
3107
3108 if (callingPid != sceneSession->GetCallingPid()) {
3109 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3110 return WSError::WS_ERROR_INVALID_PERMISSION;
3111 }
3112 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3113 };
3114
3115 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3116 }
3117
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId, const sptr<IRemoteObject>& callback)3118 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3119 const sptr<IRemoteObject>& callback)
3120 {
3121 if (callback == nullptr) {
3122 return WSError::WS_ERROR_NULLPTR;
3123 }
3124 const auto callingPid = IPCSkeleton::GetCallingRealPid();
3125 auto task = [this, persistentId, callingPid, callback]() {
3126 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3127 auto sceneSession = GetSceneSession(persistentId);
3128 if (sceneSession == nullptr) {
3129 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3130 return WSError::WS_ERROR_NULLPTR;
3131 }
3132
3133 if (callingPid != sceneSession->GetCallingPid()) {
3134 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3135 return WSError::WS_ERROR_INVALID_PERMISSION;
3136 }
3137 sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3138 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3139 };
3140
3141 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3142 }
3143
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)3144 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
3145 {
3146 if (!sceneSession) {
3147 TLOGE(WmsLogTag::WMS_SUB,"sceneSession is null");
3148 return;
3149 }
3150 auto sessionProperty = sceneSession->GetSessionProperty();
3151 if (sessionProperty && sessionProperty->GetIsUIExtFirstSubWindow() &&
3152 !sessionProperty->GetIsUIExtensionAbilityProcess()) {
3153 sceneSession->NotifyDestroy();
3154 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
3155 TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
3156 TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
3157 sceneSession->GetPersistentId(), errCode);
3158 }
3159 }
3160
GetWindowSceneConfig() const3161 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3162 {
3163 return appWindowSceneConfig_;
3164 }
3165
UpdateRotateAnimationConfig(const RotateAnimationConfig& config)3166 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3167 {
3168 auto task = [this, config] {
3169 TLOGNI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3170 rotateAnimationConfig_.duration_ = config.duration_;
3171 };
3172 taskScheduler_->PostAsyncTask(task, __func__);
3173 }
3174
ProcessBackEvent()3175 WSError SceneSessionManager::ProcessBackEvent()
3176 {
3177 auto task = [this]() {
3178 auto session = GetSceneSession(focusedSessionId_);
3179 if (!session) {
3180 WLOGFE("session is nullptr: %{public}d", focusedSessionId_);
3181 return WSError::WS_ERROR_INVALID_SESSION;
3182 }
3183 WLOGFI("ProcessBackEvent session persistentId:%{public}d needBlock::%{public}d",
3184 focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3185 if (needBlockNotifyFocusStatusUntilForeground_) {
3186 WLOGFD("RequestSessionBack when start session");
3187 if (session->GetSessionInfo().abilityInfo != nullptr &&
3188 session->GetSessionInfo().abilityInfo->unclearableMission) {
3189 TLOGI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3190 return WSError::WS_OK;
3191 }
3192 session->RequestSessionBack(false);
3193 return WSError::WS_OK;
3194 }
3195 if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3196 rootSceneProcessBackEventFunc_();
3197 } else {
3198 session->ProcessBackEvent();
3199 }
3200 return WSError::WS_OK;
3201 };
3202
3203 taskScheduler_->PostAsyncTask(task, "ProcessBackEvent");
3204 return WSError::WS_OK;
3205 }
3206
InitUserInfo(int32_t userId, std::string& fileDir)3207 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3208 {
3209 if (userId == DEFAULT_USERID || fileDir.empty()) {
3210 TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3211 return WSError::WS_DO_NOTHING;
3212 }
3213 TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3214 auto task = [this, userId, &fileDir]() {
3215 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3216 TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3217 }
3218 if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3219 TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3220 }
3221 currentUserId_ = userId;
3222 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3223 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
3224 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
3225 }
3226 RegisterSecSurfaceInfoListener();
3227 return WSError::WS_OK;
3228 };
3229 return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3230 }
3231
IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)3232 bool SceneSessionManager::IsNeedChangeLifeCycleOnUserSwitch(const sptr<SceneSession>& sceneSession, int32_t pid)
3233 {
3234 auto sessionState = sceneSession->GetSessionState();
3235 auto isInvalidMainSession = !WindowHelper::IsMainWindow(sceneSession->GetWindowType()) ||
3236 sessionState == SessionState::STATE_DISCONNECT ||
3237 sessionState == SessionState::STATE_END;
3238 if (isInvalidMainSession) {
3239 TLOGD(WmsLogTag::WMS_MULTI_USER, "persistentId: %{public}d, type: %{public}d, state: %{public}d",
3240 sceneSession->GetPersistentId(), sceneSession->GetWindowType(), sceneSession->GetSessionState());
3241 }
3242 return sceneSession->GetCallingPid() != pid && IsPcSceneSessionLifecycle(sceneSession) && !isInvalidMainSession;
3243 }
3244
StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)3245 WSError SceneSessionManager::StartOrMinimizeUIAbilityBySCB(const sptr<SceneSession>& sceneSession, bool isUserActive)
3246 {
3247 auto persistentId = sceneSession->GetPersistentId();
3248 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3249 if (!abilitySessionInfo) {
3250 TLOGE(WmsLogTag::WMS_MULTI_USER, "Create Ability info failed, id %{public}d", persistentId);
3251 return WSError::WS_ERROR_NULLPTR;
3252 }
3253 if (!isUserActive) {
3254 TLOGI(WmsLogTag::WMS_MULTI_USER,
3255 "MinimizeUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
3256 sceneSession->GetWindowType(), sceneSession->GetSessionState());
3257 bool isFromUser = false;
3258 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(
3259 abilitySessionInfo, isFromUser, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
3260 if (errCode == ERR_OK) {
3261 sceneSession->SetMinimizedFlagByUserSwitch(true);
3262 } else {
3263 TLOGE(WmsLogTag::WMS_MULTI_USER, "minimize failed! errCode: %{public}d", errCode);
3264 }
3265 } else if (sceneSession->IsMinimizedByUserSwitch()) {
3266 TLOGI(WmsLogTag::WMS_MULTI_USER,
3267 "StartUIAbilityBySCB with persistentId: %{public}d, type: %{public}d, state: %{public}d", persistentId,
3268 sceneSession->GetWindowType(), sceneSession->GetSessionState());
3269 sceneSession->SetMinimizedFlagByUserSwitch(false);
3270 bool isColdStart = false;
3271 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(
3272 abilitySessionInfo, isColdStart, static_cast<uint32_t>(WindowStateChangeReason::USER_SWITCH));
3273 if (errCode != ERR_OK) {
3274 TLOGE(WmsLogTag::WMS_MULTI_USER, "start failed! errCode: %{public}d", errCode);
3275 sceneSession->NotifySessionExceptionInner(abilitySessionInfo, true);
3276 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
3277 startUIAbilityErrorFunc_(
3278 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
3279 }
3280 }
3281 }
3282 return WSError::WS_OK;
3283 }
3284
NotifySwitchingUser(const bool isUserActive)3285 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3286 {
3287 const char* const where = __func__;
3288 auto task = [this, isUserActive, where]() {
3289 TLOGNI(WmsLogTag::WMS_MULTI_USER, "%{public}s: IsUserActive=%{public}u, currentUserId=%{public}d", where,
3290 isUserActive, currentUserId_);
3291 isUserBackground_ = !isUserActive;
3292 SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3293 if (isUserActive) { // switch to current user
3294 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3295 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
3296 MultiInstanceManager::GetInstance().SetCurrentUserId(currentUserId_);
3297 }
3298 // notify screenSessionManager to recover current user
3299 ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3300 FlushWindowInfoToMMI(true);
3301 NotifyAllAccessibilityInfo();
3302 } else { // switch to another user
3303 SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3304 }
3305
3306 // Change app life cycle in pc when user switch, do app freeze
3307 int32_t pid = GetPid();
3308 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3309 for (const auto& [_, sceneSession] : sceneSessionMap_) {
3310 if (sceneSession == nullptr) {
3311 TLOGNE(WmsLogTag::WMS_MULTI_USER, "%{public}s: session is null", where);
3312 continue;
3313 }
3314 if (IsNeedChangeLifeCycleOnUserSwitch(sceneSession, pid)) {
3315 StartOrMinimizeUIAbilityBySCB(sceneSession, isUserActive);
3316 }
3317 }
3318 return WSError::WS_OK;
3319 };
3320 taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3321 }
3322
GetBundleManager()3323 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3324 {
3325 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3326 if (systemAbilityMgr == nullptr) {
3327 WLOGFE("Failed to get SystemAbilityManager.");
3328 return nullptr;
3329 }
3330
3331 auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3332 if (bmsObj == nullptr) {
3333 WLOGFE("Failed to get BundleManagerService.");
3334 return nullptr;
3335 }
3336
3337 return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3338 }
3339
GetResourceManager( const AppExecFwk::AbilityInfo& abilityInfo)3340 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3341 const AppExecFwk::AbilityInfo& abilityInfo)
3342 {
3343 auto context = rootSceneContextWeak_.lock();
3344 if (!context) {
3345 WLOGFE("context is nullptr.");
3346 return nullptr;
3347 }
3348 auto resourceMgr = context->GetResourceManager();
3349 if (!resourceMgr) {
3350 WLOGFE("resourceMgr is nullptr.");
3351 return nullptr;
3352 }
3353 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3354 if (!resConfig) {
3355 WLOGFE("resConfig is nullptr.");
3356 return nullptr;
3357 }
3358 resourceMgr->GetResConfig(*resConfig);
3359 resourceMgr = Global::Resource::CreateResourceManager(
3360 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3361 if (!resourceMgr) {
3362 WLOGFE("resourceMgr is nullptr.");
3363 return nullptr;
3364 }
3365 resourceMgr->UpdateResConfig(*resConfig);
3366
3367 std::string loadPath;
3368 if (!abilityInfo.hapPath.empty()) { // zipped hap
3369 loadPath = abilityInfo.hapPath;
3370 } else {
3371 loadPath = abilityInfo.resourcePath;
3372 }
3373
3374 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3375 WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3376 }
3377 return resourceMgr;
3378 }
3379
GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo, std::string& path, uint32_t& bgColor)3380 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3381 std::string& path, uint32_t& bgColor)
3382 {
3383 auto resourceMgr = GetResourceManager(abilityInfo);
3384 if (!resourceMgr) {
3385 WLOGFE("resourceMgr is nullptr.");
3386 return false;
3387 }
3388
3389 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3390 WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3391 return false;
3392 }
3393
3394 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3395 WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3396 return false;
3397 }
3398
3399 if (!abilityInfo.hapPath.empty()) { // zipped hap
3400 auto pos = path.find_last_of('.');
3401 if (pos == std::string::npos) {
3402 WLOGFE("Format error, path %{private}s.", path.c_str());
3403 return false;
3404 }
3405 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3406 }
3407 return true;
3408 }
3409
GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)3410 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3411 {
3412 if (!bundleMgr_) {
3413 WLOGFE("bundleMgr_ is nullptr.");
3414 return;
3415 }
3416 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3417 if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3418 WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3419 return;
3420 }
3421 AAFwk::Want want;
3422 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3423 AppExecFwk::AbilityInfo abilityInfo;
3424 if (!bundleMgr_->QueryAbilityInfo(
3425 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3426 WLOGFE("Get ability info from BMS failed!");
3427 return;
3428 }
3429
3430 if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3431 CacheStartingWindowInfo(abilityInfo, path, bgColor);
3432 }
3433 WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3434 abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3435 }
3436
GetStartingWindowInfoFromCache( const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)3437 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3438 const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3439 {
3440 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3441 std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3442 auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3443 if (iter == startingWindowMap_.end()) {
3444 return false;
3445 }
3446 auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3447 const auto& infoMap = iter->second;
3448 auto infoMapIter = infoMap.find(key);
3449 if (infoMapIter == infoMap.end()) {
3450 return false;
3451 }
3452 path = infoMapIter->second.startingWindowIconPath_;
3453 bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3454 return true;
3455 }
3456
CacheStartingWindowInfo( const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)3457 void SceneSessionManager::CacheStartingWindowInfo(
3458 const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3459 {
3460 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3461 auto key = abilityInfo.moduleName + abilityInfo.name;
3462 StartingWindowInfo info = {
3463 .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3464 .startingWindowIconId_ = abilityInfo.startWindowIconId,
3465 .startingWindowBackgroundColor_ = bgColor,
3466 .startingWindowIconPath_ = path,
3467 };
3468 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3469 auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3470 if (iter != startingWindowMap_.end()) {
3471 auto& infoMap = iter->second;
3472 infoMap.emplace(key, info);
3473 return;
3474 }
3475 if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3476 startingWindowMap_.erase(startingWindowMap_.begin());
3477 }
3478 std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3479 startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3480 }
3481
OnBundleUpdated(const std::string& bundleName, int userId)3482 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3483 {
3484 taskScheduler_->PostAsyncTask([this, bundleName]() {
3485 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3486 auto iter = startingWindowMap_.find(bundleName);
3487 if (iter != startingWindowMap_.end()) {
3488 startingWindowMap_.erase(iter);
3489 }
3490 },
3491 "OnBundleUpdated");
3492 }
3493
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)3494 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3495 {
3496 taskScheduler_->PostAsyncTask([this]() {
3497 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3498 startingWindowMap_.clear();
3499 },
3500 "OnConfigurationUpdated");
3501 }
3502
FillSessionInfo(sptr<SceneSession>& sceneSession)3503 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3504 {
3505 auto sessionInfo = sceneSession->GetSessionInfo();
3506 if (sessionInfo.bundleName_.empty()) {
3507 WLOGFE("bundleName_ is empty");
3508 return;
3509 }
3510 if (sessionInfo.isSystem_) {
3511 WLOGFD("is system scene!");
3512 return;
3513 }
3514 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3515 sessionInfo.moduleName_);
3516 if (abilityInfo == nullptr) {
3517 WLOGFE("abilityInfo is nullptr!");
3518 return;
3519 }
3520 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3521 sceneSession->SetSessionInfoTime(GetCurrentTime());
3522 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3523 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3524 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3525 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3526 }
3527 TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3528 "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3529 abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3530 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3531 }
3532
QueryAbilityInfoFromBMS(const int32_t uId, const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)3533 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3534 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3535 {
3536 if (!bundleMgr_) {
3537 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3538 return nullptr;
3539 }
3540 SessionInfoList list = {
3541 .uid_ = uId, .bundleName_ = bundleName, .abilityName_ = abilityName, .moduleName_ = moduleName
3542 };
3543 if (abilityInfoMap_.count(list)) {
3544 return abilityInfoMap_[list];
3545 }
3546 AAFwk::Want want;
3547 want.SetElementName("", bundleName, abilityName, moduleName);
3548 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3549 if (abilityInfo == nullptr) {
3550 WLOGFE("abilityInfo is nullptr!");
3551 return nullptr;
3552 }
3553 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3554 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3555 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3556 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
3557 if (!ret) {
3558 WLOGFE("Get ability info from BMS failed!");
3559 return nullptr;
3560 }
3561 abilityInfoMap_[list] = abilityInfo;
3562 return abilityInfo;
3563 }
3564
GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session, uint32_t& topWinId, uint32_t& zOrder)3565 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
3566 uint32_t& topWinId, uint32_t& zOrder)
3567 {
3568 const auto& subVec = session->GetSubSession();
3569 for (const auto& subSession : subVec) {
3570 if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
3571 TLOGW(WmsLogTag::WMS_SUB,
3572 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
3573 continue;
3574 }
3575 if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3576 subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
3577 subSession->GetZOrder() > zOrder) {
3578 topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
3579 zOrder = subSession->GetZOrder();
3580 TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
3581 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
3582 }
3583 if (subSession->GetSubSession().size() > 0) {
3584 GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
3585 }
3586 }
3587 }
3588
3589 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)3590 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
3591 {
3592 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3593 auto task = [this, mainWinId, &topWinId, callingPid]() {
3594 const auto& mainSession = GetSceneSession(mainWinId);
3595 if (mainSession == nullptr) {
3596 return WMError::WM_ERROR_INVALID_WINDOW;
3597 }
3598
3599 if (callingPid != mainSession->GetCallingPid()) {
3600 WLOGFE("Permission denied, not destroy by the same process");
3601 return WMError::WM_ERROR_INVALID_PERMISSION;
3602 }
3603 uint32_t zOrder = mainSession->GetZOrder();
3604 topWinId = mainWinId;
3605 GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
3606 TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
3607 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
3608 return WMError::WM_OK;
3609 };
3610
3611 if (!Session::IsScbCoreEnabled()) {
3612 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3613 }
3614 bool postNow = false;
3615 auto mainSession = GetSceneSession(mainWinId);
3616 if (mainSession != nullptr) {
3617 postNow = !(mainSession->GetUIStateDirty());
3618 }
3619 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
3620 if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
3621 taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
3622 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3623 }
3624 TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
3625 {
3626 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
3627 if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
3628 std::cv_status::timeout) {
3629 TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
3630 }
3631 }
3632 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3633 }
3634
GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap, int32_t windowId, int32_t& mainWindowId)3635 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
3636 int32_t windowId, int32_t& mainWindowId)
3637 {
3638 auto iter = sceneSessionMap.find(windowId);
3639 if (iter == sceneSessionMap.end()) {
3640 TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
3641 return WMError::WM_ERROR_NULLPTR;
3642 }
3643 sptr<SceneSession> sceneSession = iter->second;
3644 if (sceneSession == nullptr) {
3645 TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
3646 return WMError::WM_ERROR_NULLPTR;
3647 }
3648 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3649 mainWindowId = sceneSession->GetPersistentId();
3650 return WMError::WM_OK;
3651 }
3652 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3653 WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
3654 return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
3655 }
3656 // not sub window, dialog, return invalid id
3657 mainWindowId = INVALID_SESSION_ID;
3658 return WMError::WM_OK;
3659 }
3660
GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)3661 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
3662 {
3663 if (windowId == INVALID_SESSION_ID) {
3664 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3665 return WMError::WM_ERROR_INVALID_PARAM;
3666 }
3667 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3668 return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
3669 }
3670
HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)3671 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
3672 const sptr<SceneSession>& sceneSession)
3673 {
3674 auto systemBarProperties = property->GetSystemBarProperty();
3675 for (auto iter : systemBarProperties) {
3676 if (iter.first == type) {
3677 sceneSession->SetSystemBarProperty(iter.first, iter.second);
3678 TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
3679 static_cast<int32_t>(iter.first), iter.second.enable_);
3680 }
3681 }
3682 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3683 }
3684
3685 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)3686 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
3687 const sptr<SceneSession>& sceneSession)
3688 {
3689 if (!SessionPermission::IsSystemCalling()) {
3690 TLOGE(WmsLogTag::WMS_HIERARCHY, "UpdateTopmostProperty permission denied!");
3691 return WMError::WM_ERROR_NOT_SYSTEM_APP;
3692 }
3693
3694 sceneSession->SetTopmost(property->IsTopmost());
3695 return WMError::WM_OK;
3696 }
3697
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property, const sptr<SceneSession>& sceneSession)3698 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3699 const sptr<SceneSession>& sceneSession)
3700 {
3701 auto propertyOld = sceneSession->GetSessionProperty();
3702 if (propertyOld == nullptr) {
3703 TLOGI(WmsLogTag::DEFAULT, "session property null");
3704 return;
3705 }
3706
3707 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
3708 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
3709 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
3710 TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
3711 return;
3712 }
3713
3714 if (IsSessionVisibleForeground(sceneSession)) {
3715 if (hideNonSystemFloatingWindowsOld) {
3716 UpdateForceHideState(sceneSession, propertyOld, false);
3717 } else {
3718 UpdateForceHideState(sceneSession, property, true);
3719 }
3720 }
3721 }
3722
UpdateForceHideState(const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property, bool add)3723 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
3724 const sptr<WindowSessionProperty>& property, bool add)
3725 {
3726 if (property == nullptr) {
3727 WLOGFD("property is null");
3728 return;
3729 }
3730 auto persistentId = sceneSession->GetPersistentId();
3731 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
3732 bool notifyAll = false;
3733 if (add) {
3734 if (property->GetHideNonSystemFloatingWindows()) {
3735 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
3736 notifyAll = !forceHideFloatOld;
3737 } else if (property->IsFloatingWindowAppType() && !property->GetSystemCalling()) {
3738 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
3739 if (forceHideFloatOld) {
3740 sceneSession->NotifyForceHideChange(true);
3741 }
3742 }
3743 } else {
3744 if (property->GetHideNonSystemFloatingWindows()) {
3745 systemTopSceneSessionMap_.erase(persistentId);
3746 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
3747 } else if (property->IsFloatingWindowAppType() && !property->GetSystemCalling()) {
3748 nonSystemFloatSceneSessionMap_.erase(persistentId);
3749 if (property->GetForceHide()) {
3750 sceneSession->NotifyForceHideChange(false);
3751 }
3752 }
3753 }
3754 if (notifyAll) {
3755 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
3756 for (const auto &item : nonSystemFloatSceneSessionMap_) {
3757 auto forceHideSceneSession = item.second;
3758 auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
3759 if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
3760 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
3761 }
3762 }
3763 }
3764 }
3765
HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)3766 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
3767 {
3768 #ifdef POWER_MANAGER_ENABLE
3769 auto task = [this, sceneSession]() {
3770 if (sceneSession == nullptr) {
3771 WLOGFE("session is invalid");
3772 return;
3773 }
3774 WLOGFD("Win: %{public}s, is turn on%{public}d",
3775 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
3776 std::string identity = IPCSkeleton::ResetCallingIdentity();
3777 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
3778 WLOGI("turn screen on");
3779 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
3780 }
3781 // set ipc identity to raw
3782 IPCSkeleton::SetCallingIdentity(identity);
3783 };
3784 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
3785
3786 #else
3787 WLOGFD("Can not found the sub system of PowerMgr");
3788 #endif
3789 }
3790
HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)3791 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
3792 {
3793 #ifdef POWER_MANAGER_ENABLE
3794 wptr<SceneSession> weakSceneSession(sceneSession);
3795 auto task = [this, weakSceneSession, requireLock]() {
3796 auto scnSession = weakSceneSession.promote();
3797 if (scnSession == nullptr) {
3798 WLOGFE("session is invalid");
3799 return;
3800 }
3801 if (requireLock && scnSession->keepScreenLock_ == nullptr) {
3802 // reset ipc identity
3803 std::string identity = IPCSkeleton::ResetCallingIdentity();
3804 scnSession->keepScreenLock_ =
3805 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
3806 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
3807 // set ipc identity to raw
3808 IPCSkeleton::SetCallingIdentity(identity);
3809 }
3810 if (scnSession->keepScreenLock_ == nullptr) {
3811 return;
3812 }
3813 bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession);
3814 TLOGNI(WmsLogTag::DEFAULT, "keep screen on: [%{public}s, %{public}d, %{public}d], %{public}d], %{public}d]",
3815 scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
3816 scnSession->IsVisible(), requireLock, shouldLock);
3817 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
3818 ErrCode res;
3819 std::string identity = IPCSkeleton::ResetCallingIdentity();
3820 if (shouldLock) {
3821 res = scnSession->keepScreenLock_->Lock();
3822 } else {
3823 res = scnSession->keepScreenLock_->UnLock();
3824 }
3825 // set ipc identity to raw
3826 IPCSkeleton::SetCallingIdentity(identity);
3827 if (res != ERR_OK) {
3828 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
3829 requireLock, res);
3830 }
3831 };
3832 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
3833 #else
3834 WLOGFD("Can not found the sub system of PowerMgr");
3835 #endif
3836 }
3837
NotifyVisibleChange(int32_t persistentId)3838 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
3839 {
3840 auto sceneSession = GetSceneSession(persistentId);
3841 if (sceneSession == nullptr) {
3842 return false;
3843 }
3844 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
3845 ProcessWindowModeType();
3846 return true;
3847 }
3848
SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)3849 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
3850 {
3851 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
3852 if (GetDisplayBrightness() != brightness &&
3853 GetFocusedSessionId() == sceneSession->GetPersistentId()) {
3854 bool setBrightnessRet = false;
3855 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3856 auto task = []() {
3857 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3858 };
3859 setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
3860 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3861 } else {
3862 auto task = [brightness]() {
3863 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3864 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3865 };
3866 setBrightnessRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
3867 SetDisplayBrightness(brightness);
3868 }
3869 if (!setBrightnessRet) {
3870 WLOGFE("Report post listener callback task failed. the task name is SetBrightness");
3871 }
3872 }
3873 #else
3874 WLOGFD("Can not found the sub system of DisplayPowerMgr");
3875 #endif
3876 brightnessSessionId_ = sceneSession->GetPersistentId();
3877 return WSError::WS_OK;
3878 }
3879
UpdateBrightness(int32_t persistentId)3880 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
3881 {
3882 auto sceneSession = GetSceneSession(persistentId);
3883 if (sceneSession == nullptr) {
3884 WLOGFE("session is invalid");
3885 return WSError::WS_ERROR_NULLPTR;
3886 }
3887 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
3888 sceneSession->GetSessionInfo().isSystem_)) {
3889 WLOGW("only app main window can set brightness");
3890 return WSError::WS_DO_NOTHING;
3891 }
3892 auto brightness = sceneSession->GetBrightness();
3893 WLOGFI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
3894 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
3895 if (GetDisplayBrightness() != brightness) {
3896 WLOGI("adjust brightness with default value");
3897 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
3898 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
3899 }
3900 brightnessSessionId_ = INVALID_WINDOW_ID;
3901 } else {
3902 if (GetDisplayBrightness() != brightness) {
3903 WLOGI("adjust brightness with value");
3904 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
3905 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
3906 SetDisplayBrightness(brightness);
3907 }
3908 brightnessSessionId_ = sceneSession->GetPersistentId();
3909 }
3910 return WSError::WS_OK;
3911 }
3912
GetCurrentUserId() const3913 int32_t SceneSessionManager::GetCurrentUserId() const
3914 {
3915 return currentUserId_;
3916 }
3917
SetDisplayBrightness(float brightness)3918 void SceneSessionManager::SetDisplayBrightness(float brightness)
3919 {
3920 displayBrightness_ = brightness;
3921 }
3922
GetDisplayBrightness() const3923 float SceneSessionManager::GetDisplayBrightness() const
3924 {
3925 return displayBrightness_;
3926 }
3927
SetGestureNavigationEnabled(bool enable)3928 WMError SceneSessionManager::SetGestureNavigationEnabled(bool enable)
3929 {
3930 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
3931 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
3932 return WMError::WM_ERROR_NOT_SYSTEM_APP;
3933 }
3934 std::string callerBundleName = SessionPermission::GetCallingBundleName();
3935 TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
3936 auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
3937 SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
3938 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
3939 WLOGFE("callback func is null");
3940 return WMError::WM_OK;
3941 }
3942 if (gestureNavigationEnabledChangeFunc_) {
3943 gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
3944 }
3945 if (statusBarEnabledChangeFunc_) {
3946 statusBarEnabledChangeFunc_(enable, bundleName);
3947 }
3948 return WMError::WM_OK;
3949 };
3950 return taskScheduler_->PostSyncTask(task, "SetGestureNavigationEnabled");
3951 }
3952
SetFocusedSessionId(int32_t persistentId)3953 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
3954 {
3955 if (focusedSessionId_ == persistentId) {
3956 WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
3957 return WSError::WS_DO_NOTHING;
3958 }
3959 lastFocusedSessionId_ = focusedSessionId_;
3960 focusedSessionId_ = persistentId;
3961 return WSError::WS_OK;
3962 }
3963
GetFocusedSessionId() const3964 int32_t SceneSessionManager::GetFocusedSessionId() const
3965 {
3966 return focusedSessionId_;
3967 }
3968
GetFocusWindowInfo(FocusChangeInfo& focusInfo)3969 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
3970 {
3971 if (!SessionPermission::IsSACalling()) {
3972 WLOGFE("GetFocusWindowInfo permission denied!");
3973 return;
3974 }
3975 auto sceneSession = GetSceneSession(focusedSessionId_);
3976 if (sceneSession) {
3977 WLOGFD("Get focus session info success");
3978 focusInfo.windowId_ = sceneSession->GetWindowId();
3979 focusInfo.displayId_ = static_cast<DisplayId>(0);
3980 focusInfo.pid_ = sceneSession->GetCallingPid();
3981 focusInfo.uid_ = sceneSession->GetCallingUid();
3982 focusInfo.windowType_ = sceneSession->GetWindowType();
3983 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
3984 }
3985 return;
3986 }
3987
IsValidDigitString(const std::string& windowIdStr)3988 static bool IsValidDigitString(const std::string& windowIdStr)
3989 {
3990 if (windowIdStr.empty()) {
3991 return false;
3992 }
3993 for (char ch : windowIdStr) {
3994 if ((ch >= '0' && ch <= '9')) {
3995 continue;
3996 }
3997 WLOGFE("invalid window id");
3998 return false;
3999 }
4000 return true;
4001 }
4002
RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)4003 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
4004 {
4005 if (sceneSession == nullptr) {
4006 WLOGFE("session is nullptr");
4007 return;
4008 }
4009 NotifySessionExceptionFunc sessionExceptionFunc = [this](const SessionInfo& info, bool needRemoveSession = false) {
4010 auto task = [this, info] {
4011 auto session = GetSceneSession(info.persistentId_);
4012 if (session == nullptr) {
4013 WLOGW("NotifySessionExceptionFunc, Not found session, id: %{public}d",
4014 info.persistentId_);
4015 return;
4016 }
4017 if (session->GetSessionInfo().isSystem_) {
4018 WLOGW("NotifySessionExceptionFunc, id: %{public}d is system",
4019 session->GetPersistentId());
4020 return;
4021 }
4022 WLOGI("NotifySessionExceptionFunc, errorCode: %{public}d, id: %{public}d",
4023 info.errorCode, info.persistentId_);
4024 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
4025 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
4026 WLOGD("NotifySessionClosed when ability load timeout "
4027 "or foreground timeout, id: %{public}d", info.persistentId_);
4028 listenerController_->NotifySessionClosed(info.persistentId_);
4029 }
4030 };
4031 taskScheduler_->PostVoidSyncTask(task, "sessionException");
4032 };
4033 sceneSession->SetSessionExceptionListener(sessionExceptionFunc, false);
4034 TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
4035 }
4036
RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)4037 void SceneSessionManager::RegisterVisibilityChangedDetectFunc(const sptr<SceneSession>& sceneSession)
4038 {
4039 if (sceneSession == nullptr) {
4040 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
4041 return;
4042 }
4043 VisibilityChangedDetectFunc func = [this](const int32_t pid, const bool isVisible,
4044 const bool newIsVisible) {
4045 if (isVisible == newIsVisible || pid == -1) {
4046 return;
4047 }
4048 sptr<WindowPidVisibilityInfo> windowPidVisibilityInfo = sptr<WindowPidVisibilityInfo>::MakeSptr();
4049 windowPidVisibilityInfo->pid_ = pid;
4050 int32_t count = 0;
4051 int32_t beforeCount = 0;
4052 {
4053 std::unique_lock<std::mutex> lock(visibleWindowCountMapMutex_);
4054 if (visibleWindowCountMap_.find(pid) != visibleWindowCountMap_.end()) {
4055 beforeCount = visibleWindowCountMap_[pid];
4056 }
4057 count = newIsVisible ? beforeCount + 1 : beforeCount - 1;
4058 }
4059 if (beforeCount == 0 && count == 1) {
4060 TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to visibility.", pid);
4061 windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::VISIBILITY_STATE;
4062 visibleWindowCountMap_[pid] = count;
4063 SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
4064 } else if (beforeCount == 1 && count == 0) {
4065 TLOGI(WmsLogTag::WMS_LIFE, "The windows of pid %{public}d change to invisibility.", pid);
4066 windowPidVisibilityInfo->visibilityState_ = WindowPidVisibilityState::INVISIBILITY_STATE;
4067 visibleWindowCountMap_.erase(pid);
4068 SessionManagerAgentController::GetInstance().NotifyWindowPidVisibilityChanged(windowPidVisibilityInfo);
4069 } else if (beforeCount < 0 || count < 0) {
4070 TLOGE(WmsLogTag::WMS_LIFE, "The count of visible windows in same pid:%{public}d is less than 0.", pid);
4071 RecoveryVisibilityPidCount(pid);
4072 } else {
4073 visibleWindowCountMap_[pid] = count;
4074 }
4075 };
4076 sceneSession->SetVisibilityChangedDetectFunc(func);
4077 }
4078
RecoveryVisibilityPidCount(int32_t pid)4079 void SceneSessionManager::RecoveryVisibilityPidCount(int32_t pid)
4080 {
4081 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4082 int32_t count = 0;
4083 for (const auto& iter : sceneSessionMap_) {
4084 auto& session = iter.second;
4085 if (session && session->GetCallingPid() == pid && session->IsVisible()) {
4086 count++;
4087 }
4088 }
4089
4090 if (count > 0) {
4091 visibleWindowCountMap_[pid] = count;
4092 }
4093 }
4094
RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)4095 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
4096 {
4097 if (sceneSession == nullptr) {
4098 WLOGFE("session is nullptr");
4099 return;
4100 }
4101 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
4102 auto sceneSession = GetSceneSession(persistentId);
4103 if (sceneSession == nullptr) {
4104 WLOGW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
4105 return;
4106 }
4107 if (sceneSession->GetSessionInfo().isSystem_) {
4108 WLOGW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
4109 return;
4110 }
4111 auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
4112 if (abilityInfoPtr == nullptr) {
4113 WLOGW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
4114 return;
4115 }
4116 if (!abilityInfoPtr->excludeFromMissions) {
4117 listenerController_->NotifySessionSnapshotChanged(persistentId);
4118 }
4119 };
4120 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
4121 WLOGFD("success, id: %{public}d", sceneSession->GetPersistentId());
4122 }
4123
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)4124 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
4125 {
4126 if (sceneSession == nullptr) {
4127 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
4128 return;
4129 }
4130 AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
4131 config.duration_ = rotateAnimationConfig_.duration_;
4132 };
4133 sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
4134 TLOGD(WmsLogTag::DEFAULT, "success, id: %{public}d",
4135 sceneSession->GetPersistentId());
4136 }
4137
NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)4138 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
4139 {
4140 if (sceneSession == nullptr) {
4141 WLOGFW("session is null");
4142 return;
4143 }
4144 if (sceneSession->GetSessionInfo().isSystem_) {
4145 WLOGFW("id: %{public}d is system", sceneSession->GetPersistentId());
4146 return;
4147 }
4148 if (sceneSession->GetSessionInfo().appIndex_ != 0) {
4149 WLOGFI("NotifyDestroy, appIndex: %{public}d, id: %{public}d",
4150 sceneSession->GetSessionInfo().appIndex_, sceneSession->GetPersistentId());
4151 listenerController_->NotifySessionDestroyed(sceneSession->GetPersistentId());
4152 return;
4153 }
4154 if (needRemoveSession) {
4155 WLOGFI("NotifyDestroy, needRemoveSession, id: %{public}d", sceneSession->GetPersistentId());
4156 listenerController_->NotifySessionDestroyed(sceneSession->GetPersistentId());
4157 return;
4158 }
4159 if (sceneSession->GetSessionInfo().abilityInfo == nullptr) {
4160 WLOGFW("abilityInfo is null, id: %{public}d", sceneSession->GetPersistentId());
4161 } else if ((sceneSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4162 (sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4163 WLOGFI("NotifyDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4164 sceneSession->GetPersistentId());
4165 listenerController_->NotifySessionDestroyed(sceneSession->GetPersistentId());
4166 return;
4167 }
4168 WLOGFI("NotifyClosed, id: %{public}d", sceneSession->GetPersistentId());
4169 listenerController_->NotifySessionClosed(sceneSession->GetPersistentId());
4170 }
4171
NotifyWindowInfoChangeFromSession(int32_t persistentId)4172 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4173 {
4174 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4175 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4176 if (sceneSession == nullptr) {
4177 WLOGFE("sceneSession nullptr");
4178 return;
4179 }
4180
4181 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4182 }
4183
IsSessionVisible(const sptr<SceneSession>& session)4184 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4185 {
4186 if (session == nullptr) {
4187 return false;
4188 }
4189 if (Session::IsScbCoreEnabled()) {
4190 return session->IsVisible();
4191 }
4192 const auto& state = session->GetSessionState();
4193 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4194 const auto& parentSceneSession = session->GetParentSession();
4195 if (parentSceneSession == nullptr) {
4196 WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
4197 return false;
4198 }
4199 const auto& parentState = parentSceneSession->GetSessionState();
4200 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4201 if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
4202 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
4203 return false;
4204 }
4205 WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4206 return true;
4207 }
4208 WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4209 return false;
4210 }
4211
4212 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4213 WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
4214 return true;
4215 }
4216 WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
4217 return false;
4218 }
4219
IsSessionVisibleForeground(const sptr<SceneSession>& session)4220 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4221 {
4222 if (session == nullptr) {
4223 return false;
4224 }
4225 if (Session::IsScbCoreEnabled()) {
4226 return session->IsVisibleForeground();
4227 }
4228 return IsSessionVisible(session);
4229 }
4230
DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)4231 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4232 {
4233 if (session == nullptr) {
4234 return;
4235 }
4236 int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4237 WSRect rect = session->GetSessionRect();
4238 std::string sName;
4239 if (session->GetSessionInfo().isSystem_) {
4240 sName = session->GetSessionInfo().abilityName_;
4241 } else {
4242 sName = session->GetWindowName();
4243 }
4244 uint32_t flag = 0;
4245 uint64_t displayId = INVALID_SCREEN_ID;
4246 auto sessionProperty = session->GetSessionProperty();
4247 if (sessionProperty) {
4248 flag = sessionProperty->GetWindowFlags();
4249 displayId = sessionProperty->GetDisplayId();
4250 }
4251 uint32_t orientation = 0;
4252 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4253 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4254 // std::setw is used to set the output width and different width values are set to keep the format aligned.
4255 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4256 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4257 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4258 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4259 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4260 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4261 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4262 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4263 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4264 << "[ "
4265 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4266 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4267 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4268 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4269 << "]"
4270 << " [ "
4271 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4272 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4273 << "]"
4274 << " [ "
4275 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4276 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4277 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4278 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4279 << "]"
4280 << std::endl;
4281 }
4282
GetAllSessionDumpInfo(std::string& dumpInfo)4283 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4284 {
4285 int32_t screenGroupId = 0;
4286 std::ostringstream oss;
4287 oss << "-------------------------------------ScreenGroup " << screenGroupId
4288 << "-------------------------------------" << std::endl;
4289 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
4290 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]"
4291 << std::endl;
4292
4293 std::vector<sptr<SceneSession>> allSession;
4294 std::vector<sptr<SceneSession>> backgroundSession;
4295 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4296 {
4297 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4298 sceneSessionMapCopy = sceneSessionMap_;
4299 }
4300 for (const auto& elem : sceneSessionMapCopy) {
4301 auto curSession = elem.second;
4302 if (curSession == nullptr) {
4303 continue;
4304 }
4305 if (IsSessionVisibleForeground(curSession)) {
4306 allSession.push_back(curSession);
4307 } else {
4308 backgroundSession.push_back(curSession);
4309 }
4310 }
4311 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4312 uint32_t count = 0;
4313 for (const auto& session : allSession) {
4314 if (session == nullptr) {
4315 continue;
4316 }
4317 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4318 oss << "---------------------------------------------------------------------------------------"
4319 << std::endl;
4320 }
4321 DumpSessionInfo(session, oss);
4322 count++;
4323 }
4324 oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4325 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4326 dumpInfo.append(oss.str());
4327 return WSError::WS_OK;
4328 }
4329
GetAllSessionDumpDetailInfo(std::string& dumpInfo)4330 WSError SceneSessionManager::GetAllSessionDumpDetailInfo(std::string& dumpInfo)
4331 {
4332 std::ostringstream oss;
4333 std::vector<sptr<SceneSession>> allSession;
4334 std::vector<sptr<SceneSession>> backgroundSession;
4335
4336 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4337 {
4338 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4339 sceneSessionMapCopy = sceneSessionMap_;
4340 }
4341 for (const auto& elem : sceneSessionMapCopy) {
4342 auto curSession = elem.second;
4343 if (curSession == nullptr) {
4344 continue;
4345 }
4346 if (IsSessionVisibleForeground(curSession)) {
4347 allSession.push_back(curSession);
4348 } else {
4349 backgroundSession.push_back(curSession);
4350 }
4351 }
4352 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4353 HidumpController::GetInstance().GetAllSessionDumpDetailedInfo(oss, allSession, backgroundSession);
4354 dumpInfo.append(oss.str());
4355 return WSError::WS_OK;
4356 }
4357
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)4358 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4359 {
4360 dumpRootSceneFunc_ = func;
4361 }
4362
DumpSessionElementInfo(const sptr<SceneSession>& session, const std::vector<std::string>& params, std::string& dumpInfo)4363 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4364 const std::vector<std::string>& params, std::string& dumpInfo)
4365 {
4366 std::vector<std::string> resetParams;
4367 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4368 if (resetParams.empty()) {
4369 WLOGI("do not dump ui info");
4370 return;
4371 }
4372
4373 if (!session->GetSessionInfo().isSystem_) {
4374 WLOGFI("Dump normal session, not system");
4375 dumpInfoFuture_.ResetLock({});
4376 session->DumpSessionElementInfo(resetParams);
4377 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4378 for (auto& info: infos) {
4379 dumpInfo.append(info).append("\n");
4380 }
4381 } else {
4382 WLOGFI("Dump system session");
4383 std::vector<std::string> infos;
4384 dumpRootSceneFunc_(resetParams, infos);
4385 for (auto& info: infos) {
4386 dumpInfo.append(info).append("\n");
4387 }
4388 }
4389 }
4390
GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params, const std::string& strId)4391 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4392 const std::string& strId)
4393 {
4394 uint64_t persistentId = std::stoull(strId);
4395 auto session = GetSceneSession(persistentId);
4396 if (session == nullptr) {
4397 return WSError::WS_ERROR_INVALID_PARAM;
4398 }
4399 auto sessionProperty = session->GetSessionProperty();
4400 if (sessionProperty == nullptr) {
4401 return WSError::WS_ERROR_INVALID_PARAM;
4402 }
4403
4404 WSRect rect = session->GetSessionRect();
4405 std::string isVisible = session->IsVisible() ? "true" : "false";
4406 std::string focusable = session->GetFocusable() ? "true" : "false";
4407 std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4408 bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4409 std::string isPrivacyMode = privacyMode ? "true" : "false";
4410 bool isFirstFrameAvailable = true;
4411 std::ostringstream oss;
4412 oss << "WindowName: " << session->GetWindowName() << std::endl;
4413 oss << "DisplayId: " << 0 << std::endl;
4414 oss << "WinId: " << session->GetPersistentId() << std::endl;
4415 oss << "Pid: " << session->GetCallingPid() << std::endl;
4416 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4417 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4418 oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4419 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4420 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4421 oss << "IsVisible: " << isVisible << std::endl;
4422 oss << "isRSVisible: " << (session->GetRSVisible() ? "true" : "false") << std::endl;
4423 oss << "Focusable: " << focusable << std::endl;
4424 oss << "DecoStatus: " << decoStatus << std::endl;
4425 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
4426 oss << "WindowRect: " << "[ "
4427 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4428 << " ]" << std::endl;
4429 oss << "scaleX: " << session->GetScaleX() << std::endl;
4430 oss << "scaleY: " << session->GetScaleY() << std::endl;
4431 oss << "Offset: " << "[ "
4432 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4433 oss << "Scale: " << "[ "
4434 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4435 << session->GetPivotX() << ", " << session->GetPivotY()
4436 << " ]" << std::endl;
4437 dumpInfo.append(oss.str());
4438
4439 DumpSessionElementInfo(session, params, dumpInfo);
4440 return WSError::WS_OK;
4441 }
4442
GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)4443 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string&& cmd, std::string& dumpInfo)
4444 {
4445 // publish data
4446 bool ret = eventHandler_->PostSyncTask(
4447 [this, cmd = std::move(cmd)] { return scbDumpSubscriber_->Publish(cmd); }, "PublishSCBDumper");
4448 if (!ret) {
4449 return WSError::WS_ERROR_INVALID_OPERATION;
4450 }
4451 // get response event
4452 auto task = [this, &dumpInfo] {
4453 dumpInfo.append(scbDumpSubscriber_->GetDebugDumpInfo(WAIT_TIME));
4454 return WSError::WS_OK;
4455 };
4456 eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4457 return WSError::WS_OK;
4458 }
4459
NotifyDumpInfoResult(const std::vector<std::string>& info)4460 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4461 {
4462 dumpInfoFuture_.SetValue(info);
4463 WLOGFD("NotifyDumpInfoResult");
4464 }
4465
GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)4466 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4467 {
4468 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4469 WLOGFE("GetSessionDumpInfo permission denied!");
4470 return WSError::WS_ERROR_INVALID_PERMISSION;
4471 }
4472 auto task = [this, params, &dumpInfo]() {
4473 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4474 return GetAllSessionDumpInfo(dumpInfo);
4475 }
4476 if (params.size() == 1 && params[0] == ARG_DUMP_DETAIL) { // 1: params num
4477 return GetAllSessionDumpDetailInfo(dumpInfo);
4478 }
4479 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4480 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4481 }
4482 if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2: params num
4483 std::string cmd;
4484 std::for_each(params.begin() + 1, params.end(),
4485 [&cmd](const std::string& value) {
4486 cmd += value;
4487 cmd += ' ';
4488 });
4489 return GetSCBDebugDumpInfo(std::move(cmd), dumpInfo);
4490 }
4491 if (params.size() >= 2 && params[0] == ARG_DUMP_PIPLINE && IsValidDigitString(params[1])) { // 2: params num
4492 return GetTotalUITreeInfo(params[1], dumpInfo);
4493 }
4494 return WSError::WS_ERROR_INVALID_OPERATION;
4495 };
4496 return taskScheduler_->PostSyncTask(task);
4497 }
4498
GetTotalUITreeInfo(const std::string& strId, std::string& dumpInfo)4499 WSError SceneSessionManager::GetTotalUITreeInfo(const std::string& strId, std::string& dumpInfo)
4500 {
4501 TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4502 uint64_t screenId = std::stoull(strId);
4503 if (dumpUITreeFunc_) {
4504 dumpUITreeFunc_(screenId, dumpInfo);
4505 } else {
4506 TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4507 }
4508 return WSError::WS_OK;
4509 }
4510
SetDumpUITreeFunc(const DumpUITreeFunc& func)4511 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4512 {
4513 dumpUITreeFunc_ = func;
4514 }
4515
FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)4516 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4517 {
4518 // notify RS
4519 WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4520 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4521 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4522 sceneSession->GetSessionInfo().bundleName_.c_str(),
4523 sceneSession->GetSessionInfo().abilityName_.c_str(),
4524 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4525 uint64_t focusNodeId = 0; // 0 means invalid
4526 if (sceneSession->GetSurfaceNode() == nullptr) {
4527 WLOGFW("focused window surfaceNode is null");
4528 } else {
4529 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4530 }
4531 FocusAppInfo appInfo = {
4532 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4533 sceneSession->GetSessionInfo().bundleName_,
4534 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4535 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4536 }
4537
4538 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4539 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4540 {
4541 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4542 {
4543 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4544 for (auto& iter : sceneSessionMap_) {
4545 ret.push_back(iter);
4546 }
4547 }
4548 std::sort(ret.begin(), ret.end(), cmp);
4549 return ret;
4550 }
4551
TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)4552 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4553 {
4554 if (isFromTopToBottom) {
4555 TraverseSessionTreeFromTopToBottom(func);
4556 } else {
4557 TraverseSessionTreeFromBottomToTop(func);
4558 }
4559 return;
4560 }
4561
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4562 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4563 {
4564 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4565 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4566 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4567 return lhsZOrder < rhsZOrder;
4568 };
4569 auto sceneSessionVector = GetSceneSessionVector(cmp);
4570
4571 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
4572 auto session = iter->second;
4573 if (session == nullptr) {
4574 WLOGFE("session is nullptr");
4575 continue;
4576 }
4577 if (func(session)) {
4578 return;
4579 }
4580 }
4581 return;
4582 }
4583
TraverseSessionTreeFromBottomToTop(TraverseFunc func)4584 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
4585 {
4586 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4587 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4588 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4589 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4590 return lhsZOrder < rhsZOrder;
4591 };
4592 auto sceneSessionVector = GetSceneSessionVector(cmp);
4593 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
4594 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
4595 auto session = iter->second;
4596 if (session == nullptr) {
4597 WLOGFE("session is nullptr");
4598 continue;
4599 }
4600 if (func(session)) {
4601 return;
4602 }
4603 }
4604 return;
4605 }
4606
RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground, FocusChangeReason reason)4607 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
4608 FocusChangeReason reason)
4609 {
4610 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4611 auto sceneSession = GetSceneSession(persistentId);
4612 if (sceneSession == nullptr) {
4613 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
4614 return WMError::WM_ERROR_NULLPTR;
4615 }
4616 int32_t callingPid = IPCSkeleton::GetCallingPid();
4617 if (callingPid != sceneSession->GetCallingPid() &&
4618 !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
4619 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
4620 return WMError::WM_ERROR_INVALID_CALLING;
4621 }
4622 auto task = [this, persistentId, isFocused, byForeground, reason]() {
4623 if (isFocused) {
4624 RequestSessionFocus(persistentId, byForeground, reason);
4625 } else {
4626 RequestSessionUnfocus(persistentId, reason);
4627 }
4628 };
4629 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
4630 focusChangeReason_ = reason;
4631 return WMError::WM_OK;
4632 }
4633
RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground, FocusChangeReason reason)4634 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
4635 FocusChangeReason reason)
4636 {
4637 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4638 auto task = [this, persistentId, isFocused, byForeground, reason]() {
4639 if (isFocused) {
4640 if (reason == FocusChangeReason::FOREGROUND) {
4641 RequestSessionFocusImmediately(persistentId);
4642 return;
4643 }
4644 if (reason == FocusChangeReason::MOVE_UP) {
4645 auto session = GetSceneSession(persistentId);
4646 if (session && !session->IsFocused()) {
4647 PostProcessFocusState state = { true, true, byForeground, reason };
4648 session->SetPostProcessFocusState(state);
4649 }
4650 return;
4651 }
4652 if (reason == FocusChangeReason::CLICK) {
4653 return;
4654 }
4655 if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
4656 auto session = GetSceneSession(persistentId);
4657 if (session && !session->IsFocused()) {
4658 PostProcessFocusState state = { true, true, byForeground, reason };
4659 session->SetPostProcessFocusState(state);
4660 }
4661 }
4662 } else {
4663 RequestSessionUnfocus(persistentId, reason);
4664 }
4665 };
4666 taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
4667 return WMError::WM_OK;
4668 }
4669
RequestAllAppSessionUnfocus()4670 void SceneSessionManager::RequestAllAppSessionUnfocus()
4671 {
4672 auto task = [this]() {
4673 RequestAllAppSessionUnfocusInner();
4674 };
4675 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
4676 return;
4677 }
4678
4679 /**
4680 * request focus and ignore its state
4681 * only used when app main window start before foreground
4682 */
RequestSessionFocusImmediately(int32_t persistentId)4683 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
4684 {
4685 TLOGI(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
4686 // base block
4687 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4688 if (basicCheckRet != WSError::WS_OK) {
4689 return basicCheckRet;
4690 }
4691 auto sceneSession = GetSceneSession(persistentId);
4692 if (sceneSession == nullptr) {
4693 WLOGFE("[WMSComm]session is nullptr");
4694 return WSError::WS_ERROR_INVALID_SESSION;
4695 }
4696 if (!sceneSession->CheckFocusable()) {
4697 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
4698 return WSError::WS_DO_NOTHING;
4699 }
4700 if (!sceneSession->IsFocusedOnShow()) {
4701 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4702 return WSError::WS_DO_NOTHING;
4703 }
4704
4705 // specific block
4706 FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
4707 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
4708 if (specificCheckRet != WSError::WS_OK) {
4709 return specificCheckRet;
4710 }
4711
4712 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4713 if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
4714 needBlockNotifyFocusStatusUntilForeground_ = true;
4715 }
4716 ShiftFocus(sceneSession, reason);
4717 return WSError::WS_OK;
4718 }
4719
RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)4720 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
4721 {
4722 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
4723 persistentId, byForeground, reason);
4724 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4725 if (basicCheckRet != WSError::WS_OK) {
4726 return basicCheckRet;
4727 }
4728 auto sceneSession = GetSceneSession(persistentId);
4729 if (sceneSession == nullptr) {
4730 WLOGFE("[WMSComm]session is nullptr");
4731 return WSError::WS_ERROR_INVALID_SESSION;
4732 }
4733 if (!sceneSession->CheckFocusable() || !IsSessionVisibleForeground(sceneSession)) {
4734 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
4735 return WSError::WS_DO_NOTHING;
4736 }
4737 if (!sceneSession->IsFocusedOnShow()) {
4738 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4739 return WSError::WS_DO_NOTHING;
4740 }
4741
4742 // subwindow/dialog state block
4743 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4744 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4745 GetSceneSession(sceneSession->GetParentPersistentId()) &&
4746 !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
4747 TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
4748 sceneSession->GetParentPersistentId());
4749 return WSError::WS_DO_NOTHING;
4750 }
4751 // specific block
4752 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
4753 if (specificCheckRet != WSError::WS_OK) {
4754 return specificCheckRet;
4755 }
4756
4757 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4758 needBlockNotifyFocusStatusUntilForeground_ = false;
4759 ShiftFocus(sceneSession, reason);
4760 return WSError::WS_OK;
4761 }
4762
RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)4763 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
4764 {
4765 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
4766 if (persistentId == INVALID_SESSION_ID) {
4767 WLOGFE("id is invalid");
4768 return WSError::WS_ERROR_INVALID_SESSION;
4769 }
4770 auto focusedSession = GetSceneSession(focusedSessionId_);
4771 if (persistentId != focusedSessionId_ &&
4772 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
4773 TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
4774 return WSError::WS_DO_NOTHING;
4775 }
4776 // if pop menu created by desktop request unfocus, back to desktop
4777 auto lastSession = GetSceneSession(lastFocusedSessionId_);
4778 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
4779 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
4780 RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
4781 TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
4782 return WSError::WS_OK;
4783 }
4784 auto nextSession = GetNextFocusableSession(persistentId);
4785 if (nextSession == nullptr) {
4786 DumpAllSessionFocusableInfo(persistentId);
4787 }
4788
4789 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4790 needBlockNotifyFocusStatusUntilForeground_ = false;
4791
4792 if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
4793 return WSError::WS_OK;
4794 }
4795
4796 return ShiftFocus(nextSession, reason);
4797 }
4798
RequestAllAppSessionUnfocusInner()4799 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
4800 {
4801 TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
4802 auto focusedSession = GetSceneSession(focusedSessionId_);
4803 if (!focusedSession) {
4804 TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
4805 return WSError::WS_DO_NOTHING;
4806 }
4807 if (!focusedSession->IsAppSession()) {
4808 WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
4809 return WSError::WS_DO_NOTHING;
4810 }
4811 auto nextSession = GetTopFocusableNonAppSession();
4812
4813 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4814 needBlockNotifyFocusStatusUntilForeground_ = false;
4815 return ShiftFocus(nextSession, FocusChangeReason::WIND);
4816 }
4817
RequestFocusBasicCheck(int32_t persistentId)4818 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
4819 {
4820 // basic focus rule
4821 if (persistentId == INVALID_SESSION_ID) {
4822 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
4823 return WSError::WS_ERROR_INVALID_SESSION;
4824 }
4825 if (persistentId == focusedSessionId_) {
4826 TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
4827 return WSError::WS_DO_NOTHING;
4828 }
4829 return WSError::WS_OK;
4830 }
4831
4832 /**
4833 * @note @window.focus
4834 * When high zOrder System Session unfocus, check if the last focused app window can focus.
4835 */
CheckLastFocusedAppSessionFocus( sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)4836 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
4837 sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
4838 {
4839 if (focusedSession == nullptr || nextSession == nullptr) {
4840 return false;
4841 }
4842
4843 TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
4844 lastFocusedAppSessionId_, nextSession->GetPersistentId());
4845
4846 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
4847 return false;
4848 }
4849
4850 if (!focusedSession->IsSystemSessionAboveApp()) {
4851 return false;
4852 }
4853
4854 auto mode = nextSession->GetWindowMode();
4855 // only when next session is app, and in split or floation
4856 if (nextSession->IsAppSession() &&
4857 (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
4858 mode == WindowMode::WINDOW_MODE_FLOATING)) {
4859 if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
4860 WSError::WS_OK) {
4861 return true;
4862 }
4863 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
4864 }
4865 return false;
4866 }
4867
4868 /**
4869 * When switching focus, check if the blockingType window has been traversed downwards.
4870 *
4871 * @return true: traversed downwards, false: not.
4872 */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession, sptr<SceneSession>& focusedSession, bool includingAppSession)4873 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
4874 sptr<SceneSession>& focusedSession, bool includingAppSession)
4875 {
4876 uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
4877 uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
4878 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
4879 requestSessionZOrder, focusedSessionZOrder);
4880 if (requestSessionZOrder < focusedSessionZOrder) {
4881 auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
4882 includingAppSession);
4883 uint32_t topNearestBlockingZOrder = 0;
4884 if (topNearestBlockingFocusSession) {
4885 topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
4886 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
4887 topNearestBlockingZOrder: %{public}d", requestSessionZOrder, focusedSessionZOrder,
4888 topNearestBlockingZOrder);
4889 }
4890 if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) {
4891 TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted");
4892 return true;
4893 }
4894 }
4895 TLOGD(WmsLogTag::WMS_FOCUS, "not through");
4896 return false;
4897 }
4898
CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)4899 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
4900 {
4901 bool isFocusedMainSessionTopmost =
4902 focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
4903 auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
4904 bool isFocusedSessionParentTopmost = parentSession &&
4905 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
4906 if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
4907 (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
4908 return true;
4909 }
4910 return false;
4911 }
4912
CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)4913 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
4914 {
4915 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4916 (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
4917 (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
4918 ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
4919 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
4920 return true;
4921 }
4922 return false;
4923 }
4924
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession, const sptr<SceneSession>& sceneSession, FocusChangeReason reason)4925 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
4926 const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
4927 {
4928 if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
4929 focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
4930 return false;
4931 }
4932 if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
4933 return false;
4934 }
4935 return sceneSession->GetZOrder() < focusedSession->GetZOrder();
4936 }
4937
RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground, FocusChangeReason reason)4938 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
4939 FocusChangeReason reason)
4940 {
4941 TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
4942 int32_t persistentId = sceneSession->GetPersistentId();
4943 if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
4944 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
4945 return WSError::WS_ERROR_INVALID_OPERATION;
4946 }
4947 // dialog get focus
4948 if (CheckRequestFocusImmdediately(sceneSession)) {
4949 return WSError::WS_DO_NOTHING;
4950 }
4951 // blocking-type session will block lower zOrder request focus
4952 auto focusedSession = GetSceneSession(focusedSessionId_);
4953 if (focusedSession) {
4954 TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d", reason,
4955 byForeground);
4956 if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
4957 // return ok if focused session is topmost
4958 return WSError::WS_OK;
4959 }
4960 if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
4961 sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
4962 TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
4963 byForeground = false;
4964 }
4965 if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, true)) {
4966 TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
4967 return WSError::WS_DO_NOTHING;
4968 }
4969 if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
4970 !byForeground) {
4971 if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
4972 && focusedSession->IsAppSession()) {
4973 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
4974 return WSError::WS_OK;
4975 }
4976 }
4977 bool isBlockingType = focusedSession->IsAppSession() ||
4978 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
4979 // temp check
4980 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
4981 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
4982 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
4983 persistentId);
4984 return WSError::WS_DO_NOTHING;
4985 }
4986 // desktop click temp check
4987 if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
4988 TLOGD(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
4989 return WSError::WS_DO_NOTHING;
4990 }
4991 }
4992 return WSError::WS_OK;
4993 }
4994
IsParentSessionVisible(const sptr<SceneSession>& session)4995 bool SceneSessionManager::IsParentSessionVisible(const sptr<SceneSession>& session)
4996 {
4997 if (WindowHelper::IsSubWindow(session->GetWindowType()) ||
4998 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
4999 auto parentSession = GetSceneSession(session->GetParentPersistentId());
5000 return parentSession == nullptr || IsSessionVisibleForeground(parentSession);
5001 }
5002 return true;
5003 }
5004
DumpAllSessionFocusableInfo(int32_t persistentId)5005 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
5006 {
5007 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
5008 auto func = [this](const sptr<SceneSession>& session) {
5009 if (session == nullptr) {
5010 return false;
5011 }
5012 bool parentVisible = IsParentSessionVisible(session);
5013 bool sessionVisible = IsSessionVisible(session);
5014 TLOGNI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
5015 "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
5016 session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
5017 session->GetFocusable(), sessionVisible, parentVisible);
5018 return false;
5019 };
5020 TraverseSessionTree(func, true);
5021 }
5022
GetNextFocusableSession(int32_t persistentId)5023 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
5024 {
5025 TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
5026 bool previousFocusedSessionFound = false;
5027 sptr<SceneSession> ret = nullptr;
5028 auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
5029 if (session == nullptr) {
5030 return false;
5031 }
5032 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5033 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5034 return false;
5035 }
5036 if (previousFocusedSessionFound && session->CheckFocusable() &&
5037 IsSessionVisibleForeground(session) && IsParentSessionVisible(session)) {
5038 ret = session;
5039 return true;
5040 }
5041 if (session->GetPersistentId() == persistentId) {
5042 previousFocusedSessionFound = true;
5043 }
5044 return false;
5045 };
5046 TraverseSessionTree(func, true);
5047 return ret;
5048 }
5049
5050 /**
5051 * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
5052 * and it is the closest;
5053 */
GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)5054 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
5055 {
5056 sptr<SceneSession> ret = nullptr;
5057 auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
5058 if (session == nullptr) {
5059 return false;
5060 }
5061 uint32_t sessionZOrder = session->GetZOrder();
5062 if (sessionZOrder <= zOrder) { // must be above the target session
5063 return false;
5064 }
5065 if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5066 TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
5067 return false;
5068 }
5069 auto parentSession = GetSceneSession(session->GetParentPersistentId());
5070 if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
5071 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5072 parentSession->IsTopmost()) {
5073 TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
5074 return false;
5075 }
5076 bool isPhoneOrPad = systemConfig_.IsPhoneWindow() || systemConfig_.IsPadWindow();
5077 bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
5078 (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
5079 (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
5080 if (IsSessionVisibleForeground(session) && isBlockingType) {
5081 ret = session;
5082 return true;
5083 }
5084 return false;
5085 };
5086 TraverseSessionTree(func, false);
5087 return ret;
5088 }
5089
GetTopFocusableNonAppSession()5090 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
5091 {
5092 TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
5093 sptr<SceneSession> ret = nullptr;
5094 auto func = [this, &ret](sptr<SceneSession> session) {
5095 if (session == nullptr) {
5096 return false;
5097 }
5098 if (session->IsAppSession()) {
5099 return true;
5100 }
5101 if (session->CheckFocusable() && IsSessionVisibleForeground(session)) {
5102 ret = session;
5103 }
5104 return false;
5105 };
5106 TraverseSessionTree(func, false);
5107 return ret;
5108 }
5109
SetShiftFocusListener(const ProcessShiftFocusFunc& func)5110 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
5111 {
5112 TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
5113 shiftFocusFunc_ = func;
5114 }
5115
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)5116 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5117 {
5118 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
5119 notifySCBAfterFocusedFunc_ = func;
5120 }
5121
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)5122 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5123 {
5124 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
5125 notifySCBAfterUnfocusedFunc_ = func;
5126 }
5127
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)5128 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
5129 {
5130 WLOGFD("SetCallingSessionIdSessionListenser");
5131 callingSessionIdChangeFunc_ = func;
5132 }
5133
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)5134 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
5135 {
5136 WLOGFD("SetStartUIAbilityErrorListener");
5137 startUIAbilityErrorFunc_ = func;
5138 }
5139
SetAbilityManagerCollaboratorRegisteredFunc( const AbilityManagerCollaboratorRegisteredFunc& func)5140 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
5141 const AbilityManagerCollaboratorRegisteredFunc& func)
5142 {
5143 auto task = [this, func] {
5144 abilityManagerCollaboratorRegisteredFunc_ = func;
5145 };
5146 taskScheduler_->PostAsyncTask(task, __func__);
5147 }
5148
ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)5149 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)
5150 {
5151 // unfocus
5152 int32_t focusedId = focusedSessionId_;
5153 auto focusedSession = GetSceneSession(focusedSessionId_);
5154 UpdateFocusStatus(focusedSession, false);
5155 // focus
5156 int32_t nextId = INVALID_SESSION_ID;
5157 if (nextSession == nullptr) {
5158 std::string sessionLog(GetAllSessionFocusInfo());
5159 TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
5160 focusedSessionId_, sessionLog.c_str());
5161 } else {
5162 nextId = nextSession->GetPersistentId();
5163 }
5164 UpdateFocusStatus(nextSession, true);
5165 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5166 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5167 AnomalyDetection::FocusCheckProcess(focusedId, nextId);
5168 if (!scbPrevFocus && scbCurrFocus) {
5169 if (notifySCBAfterFocusedFunc_ != nullptr) {
5170 notifySCBAfterFocusedFunc_();
5171 }
5172 } else if (scbPrevFocus && !scbCurrFocus) {
5173 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5174 notifySCBAfterUnfocusedFunc_();
5175 }
5176 }
5177 TLOGI(WmsLogTag::WMS_FOCUS, "focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5178 focusedId, nextId, reason);
5179 return WSError::WS_OK;
5180 }
5181
UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)5182 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5183 {
5184 if (sceneSession == nullptr) {
5185 if (isFocused) {
5186 SetFocusedSessionId(INVALID_SESSION_ID);
5187 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5188 }
5189 return;
5190 }
5191 TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5192 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5193 // set focused
5194 if (isFocused) {
5195 SetFocusedSessionId(sceneSession->GetPersistentId());
5196 if (sceneSession->IsAppOrLowerSystemSession()) {
5197 lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5198 }
5199 }
5200 sceneSession->UpdateFocus(isFocused);
5201 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5202 NotifyFocusStatus(sceneSession, isFocused);
5203 }
5204 }
5205
NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)5206 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5207 {
5208 if (sceneSession == nullptr) {
5209 WLOGFE("[WMSComm]session is nullptr");
5210 if (isFocused) {
5211 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5212 NotifyUnFocusedByMission(prevSession);
5213 }
5214 return;
5215 }
5216 int32_t persistentId = sceneSession->GetPersistentId();
5217
5218 TLOGI(WmsLogTag::WMS_FOCUS,
5219 "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5220 sceneSession->GetSessionInfo().bundleName_.c_str(),
5221 sceneSession->GetSessionInfo().abilityName_.c_str(),
5222 sceneSession->GetWindowNameAllType().c_str(),
5223 persistentId, isFocused);
5224 if (isFocused) {
5225 if (IsSessionVisibleForeground(sceneSession)) {
5226 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5227 }
5228 UpdateBrightness(focusedSessionId_);
5229 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5230 if (shiftFocusFunc_ != nullptr) {
5231 shiftFocusFunc_(persistentId);
5232 }
5233 }
5234 // notify window manager
5235 sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
5236 sceneSession->GetWindowId(),
5237 static_cast<DisplayId>(0),
5238 sceneSession->GetCallingPid(),
5239 sceneSession->GetCallingUid(),
5240 sceneSession->GetWindowType(),
5241 sceneSession->GetAbilityToken()
5242 );
5243 SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5244 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5245 sceneSession->NotifyFocusStatus(isFocused);
5246 std::string sName = "FoucusWindow:";
5247 if (sceneSession->GetSessionInfo().isSystem_) {
5248 sName += sceneSession->GetSessionInfo().abilityName_;
5249 } else {
5250 sName += sceneSession->GetWindowName();
5251 }
5252 if (isFocused) {
5253 StartAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
5254 } else {
5255 FinishAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
5256 }
5257
5258 // notify listenerController
5259 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5260 if (isFocused && MissionChanged(prevSession, sceneSession)) {
5261 NotifyFocusStatusByMission(prevSession, sceneSession);
5262 }
5263 }
5264
NotifyRssThawApp(const int32_t uid, const std::string& bundleName, const std::string& reason)5265 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5266 const std::string& reason)
5267 {
5268 uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5269 nlohmann::json payload;
5270 payload.emplace("uid", uid);
5271 payload.emplace("bundleName", bundleName);
5272 payload.emplace("reason", reason);
5273 nlohmann::json reply;
5274 int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5275 return ret;
5276 }
5277
NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)5278 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5279 {
5280 if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5281 TLOGD(WmsLogTag::WMS_FOCUS, "Unfocused, id: %{public}d", prevSession->GetMissionId());
5282 listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5283 }
5284 if (currSession && !currSession->GetSessionInfo().isSystem_) {
5285 TLOGD(WmsLogTag::WMS_FOCUS, "Focused, id: %{public}d", currSession->GetMissionId());
5286 listenerController_->NotifySessionFocused(currSession->GetMissionId());
5287 }
5288 }
5289
NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)5290 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5291 {
5292 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5293 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d", sceneSession->GetMissionId());
5294 listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5295 }
5296 }
5297
MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)5298 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5299 {
5300 if (prevSession == nullptr && currSession == nullptr) {
5301 return false;
5302 }
5303 if (prevSession == nullptr || currSession == nullptr) {
5304 return true;
5305 }
5306 return prevSession->GetMissionId() != currSession->GetMissionId();
5307 }
5308
GetAllSessionFocusInfo()5309 std::string SceneSessionManager::GetAllSessionFocusInfo()
5310 {
5311 std::ostringstream os;
5312 auto func = [&os](sptr<SceneSession> session) {
5313 if (session == nullptr) {
5314 WLOGE("sceneSession is nullptr");
5315 return false;
5316 }
5317 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5318 " ,focusable: "<< session->GetFocusable() << ";";
5319 return false;
5320 };
5321 TraverseSessionTree(func, true);
5322 return os.str();
5323 }
5324
UpdateFocus(int32_t persistentId, bool isFocused)5325 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5326 {
5327 auto task = [this, persistentId, isFocused]() {
5328 // notify session and client
5329 auto sceneSession = GetSceneSession(persistentId);
5330 if (sceneSession == nullptr) {
5331 WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5332 return WSError::WS_ERROR_INVALID_WINDOW;
5333 }
5334 WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5335 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5336 // focusId change
5337 if (isFocused) {
5338 SetFocusedSessionId(persistentId);
5339 UpdateBrightness(focusedSessionId_);
5340 FocusIDChange(persistentId, sceneSession);
5341 } else if (persistentId == GetFocusedSessionId()) {
5342 SetFocusedSessionId(INVALID_SESSION_ID);
5343 }
5344 // notify window manager
5345 sptr<FocusChangeInfo> focusChangeInfo = sptr<FocusChangeInfo>::MakeSptr(
5346 sceneSession->GetWindowId(),
5347 static_cast<DisplayId>(0),
5348 sceneSession->GetCallingPid(),
5349 sceneSession->GetCallingUid(),
5350 sceneSession->GetWindowType(),
5351 sceneSession->GetAbilityToken()
5352 );
5353 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5354 WSError res = WSError::WS_OK;
5355 res = sceneSession->UpdateFocus(isFocused);
5356 if (res != WSError::WS_OK) {
5357 return res;
5358 }
5359 WLOGI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5360 sceneSession->GetSessionInfo().isSystem_);
5361 if (!sceneSession->GetSessionInfo().isSystem_) {
5362 if (isFocused) {
5363 WLOGD("NotifyFocused, id: %{public}d", sceneSession->GetPersistentId());
5364 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5365 } else {
5366 WLOGD("NotifyUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5367 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5368 }
5369 }
5370 return WSError::WS_OK;
5371 };
5372
5373 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5374 return WSError::WS_OK;
5375 }
5376
UpdateWindowMode(int32_t persistentId, int32_t windowMode)5377 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5378 {
5379 WLOGFD("id: %{public}d, mode: %{public}d", persistentId, windowMode);
5380 auto sceneSession = GetSceneSession(persistentId);
5381 if (sceneSession == nullptr) {
5382 WLOGFE("could not find window, Id:%{public}d", persistentId);
5383 return WSError::WS_ERROR_INVALID_WINDOW;
5384 }
5385 WindowMode mode = static_cast<WindowMode>(windowMode);
5386 return sceneSession->UpdateWindowMode(mode);
5387 }
5388
5389 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, MMI::PointerEvent::PointerItem& pointerItem)5390 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
5391 MMI::PointerEvent::PointerItem& pointerItem)
5392 {
5393 struct PointerEventData {
5394 double x;
5395 double y;
5396 uint64_t time;
5397 } pointerEventData = {
5398 .x = pointerItem.GetDisplayX(),
5399 .y = pointerItem.GetDisplayY(),
5400 .time = pointerEvent->GetActionTime()
5401 };
5402
5403 const uint32_t MAX_HMAC_SIZE = 64;
5404 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
5405 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
5406 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
5407 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
5408 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
5409 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
5410 }
5411 }
5412 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
5413
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)5414 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
5415 {
5416 if (!pointerEvent) {
5417 WLOGFE("pointerEvent is null");
5418 return WSError::WS_ERROR_NULLPTR;
5419 }
5420 MMI::PointerEvent::PointerItem pointerItem;
5421 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
5422 WLOGFE("Failed to get pointerItem");
5423 return WSError::WS_ERROR_INVALID_PARAM;
5424 }
5425 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
5426 FillSecCompEnhanceData(pointerEvent, pointerItem);
5427 #endif
5428 TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d, action=%{public}d, deviceId=%{public}d, zIndex=%{public}ud",
5429 pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
5430 pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
5431 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
5432 return WSError::WS_OK;
5433 }
5434
SetScreenLocked(const bool isScreenLocked)5435 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
5436 {
5437 isScreenLocked_ = isScreenLocked;
5438 DeleteStateDetectTask();
5439 }
5440
DeleteStateDetectTask()5441 void SceneSessionManager::DeleteStateDetectTask()
5442 {
5443 if (!IsScreenLocked()) {
5444 return;
5445 }
5446 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5447 for (auto iter : sceneSessionMap_) {
5448 auto& session = iter.second;
5449 if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
5450 taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
5451 DetectTaskInfo detectTaskInfo;
5452 session->SetDetectTaskInfo(detectTaskInfo);
5453 }
5454 }
5455 }
5456
IsScreenLocked() const5457 bool SceneSessionManager::IsScreenLocked() const
5458 {
5459 return isScreenLocked_;
5460 }
5461
RegisterWindowChanged(const WindowChangedFunc& func)5462 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
5463 {
5464 WindowChangedFunc_ = func;
5465 }
5466
JudgeNeedNotifyPrivacyInfo(DisplayId displayId, const std::unordered_set<std::string>& privacyBundles)5467 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
5468 const std::unordered_set<std::string>& privacyBundles)
5469 {
5470 bool needNotify = false;
5471 static int reSendTimes = MAX_RESEND_TIMES;
5472 std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
5473 do {
5474 if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
5475 TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
5476 needNotify = !privacyBundles.empty();
5477 break;
5478 }
5479 const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
5480 if (lastPrivacyBundles.size() != privacyBundles.size()) {
5481 TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
5482 lastPrivacyBundles.size(), privacyBundles.size());
5483 needNotify = true;
5484 break;
5485 }
5486 for (const auto& bundle : lastPrivacyBundles) {
5487 if (privacyBundles.find(bundle) == privacyBundles.end()) {
5488 needNotify = true;
5489 break;
5490 }
5491 }
5492 } while (false);
5493
5494 TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
5495 displayId, needNotify);
5496 if (needNotify) {
5497 reSendTimes = MAX_RESEND_TIMES;
5498 privacyBundleMap_[displayId] = privacyBundles;
5499 } else if (reSendTimes > 0) {
5500 needNotify = true;
5501 reSendTimes--;
5502 privacyBundleMap_[displayId] = privacyBundles;
5503 }
5504 return needNotify;
5505 }
5506
UpdatePrivateStateAndNotify(uint32_t persistentId)5507 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
5508 {
5509 auto sceneSession = GetSceneSession(persistentId);
5510 if (sceneSession == nullptr) {
5511 TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
5512 return;
5513 }
5514
5515 auto sessionProperty = sceneSession->GetSessionProperty();
5516 if (sessionProperty == nullptr) {
5517 TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
5518 return;
5519 }
5520 auto displayId = sessionProperty->GetDisplayId();
5521 std::unordered_set<std::string> privacyBundleList;
5522 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5523 if (!JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
5524 return;
5525 }
5526
5527 std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
5528 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5529 !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
5530 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
5531 if (!bundleListForNotify.empty()) {
5532 TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
5533 }
5534 for (const auto& bundle : bundleListForNotify) {
5535 TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
5536 displayId, bundle.c_str());
5537 }
5538 }
5539
UpdatePrivateStateAndNotifyForAllScreens()5540 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
5541 {
5542 auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
5543 for (auto& iter : screenProperties) {
5544 auto displayId = iter.first;
5545 std::unordered_set<std::string> privacyBundleList;
5546 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5547
5548 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5549 !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
5550 }
5551 }
5552
GetSceneSessionPrivacyModeBundles(DisplayId displayId, std::unordered_set<std::string>& privacyBundles)5553 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
5554 std::unordered_set<std::string>& privacyBundles)
5555 {
5556 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5557 for (const auto& item : sceneSessionMap_) {
5558 sptr<SceneSession> sceneSession = item.second;
5559 if (sceneSession == nullptr) {
5560 TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
5561 continue;
5562 }
5563 auto sessionProperty = sceneSession->GetSessionProperty();
5564 if (sessionProperty == nullptr) {
5565 TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
5566 continue;
5567 }
5568 auto currentDisplayId = sessionProperty->GetDisplayId();
5569 if (displayId != currentDisplayId) {
5570 continue;
5571 }
5572 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5573 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
5574 if (isForeground && sceneSession->GetParentSession() != nullptr) {
5575 isForeground = isForeground &&
5576 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
5577 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
5578 }
5579 bool isPrivate = sessionProperty->GetPrivacyMode() ||
5580 sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
5581 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
5582 if ((isForeground || IsSystemWindowVisible) && isPrivate) {
5583 if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
5584 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
5585 } else {
5586 TLOGW(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
5587 privacyBundles.insert(sceneSession->GetWindowName());
5588 }
5589 }
5590 }
5591 }
5592
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)5593 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5594 {
5595 if (sceneSession == nullptr) {
5596 WLOGFE("session is nullptr");
5597 return;
5598 }
5599 sceneSession->SetSessionStateChangeNotifyManagerListener(
5600 [this](int32_t persistentId, const SessionState& state) THREAD_SAFETY_GUARD(SCENE_GUARD) {
5601 OnSessionStateChange(persistentId, state);
5602 });
5603 WLOGFD("success");
5604 }
5605
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)5606 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5607 {
5608 if (sceneSession == nullptr) {
5609 WLOGFE("session is nullptr");
5610 return;
5611 }
5612 sceneSession->SetSessionInfoChangeNotifyManagerListener([this](int32_t persistentId) {
5613 NotifyWindowInfoChangeFromSession(persistentId);
5614 });
5615 }
5616
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)5617 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5618 {
5619 if (sceneSession == nullptr) {
5620 WLOGFE("session is nullptr");
5621 return;
5622 }
5623 sceneSession->SetRequestFocusStatusNotifyManagerListener(
5624 [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
5625 RequestFocusStatus(persistentId, isFocused, byForeground, reason);
5626 });
5627 WLOGFD("success");
5628 }
5629
RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)5630 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
5631 {
5632 GetStateFromManagerFunc func = [this](const ManagerState key) {
5633 switch (key) {
5634 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
5635 return this->IsScreenLocked();
5636 break;
5637 default:
5638 return false;
5639 break;
5640 }
5641 };
5642 if (sceneSession == nullptr) {
5643 WLOGFE("session is nullptr");
5644 return;
5645 }
5646 sceneSession->SetGetStateFromManagerListener(func);
5647 WLOGFD("success");
5648 }
5649
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)5650 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5651 {
5652 SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
5653 const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
5654 if (sceneSession == nullptr || property == nullptr) {
5655 TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
5656 return;
5657 }
5658 switch (action) {
5659 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
5660 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
5661 break;
5662 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
5663 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
5664 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
5665 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
5666 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
5667 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
5668 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5669 break;
5670 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
5671 SetBrightness(sceneSession, property->GetBrightness());
5672 break;
5673 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
5674 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
5675 UpdatePrivateStateAndNotify(property->GetPersistentId());
5676 break;
5677 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
5678 CheckAndNotifyWaterMarkChangedResult();
5679 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5680 break;
5681 case WSPropertyChangeAction::ACTION_UPDATE_MODE:
5682 if (sceneSession->GetSessionProperty() != nullptr) {
5683 ProcessWindowModeType();
5684 }
5685 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5686 break;
5687 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5688 HandleHideNonSystemFloatingWindows(property, sceneSession);
5689 break;
5690 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
5691 FlushWindowInfoToMMI();
5692 break;
5693 default:
5694 break;
5695 }
5696 };
5697 if (sceneSession != nullptr) {
5698 sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
5699 }
5700 }
5701
OnSessionStateChange( int32_t persistentId, const SessionState& state)5702 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
5703 int32_t persistentId, const SessionState& state)
5704 {
5705 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
5706 WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
5707 auto sceneSession = GetSceneSession(persistentId);
5708 if (sceneSession == nullptr) {
5709 WLOGFD("session is nullptr");
5710 return;
5711 }
5712 switch (state) {
5713 case SessionState::STATE_FOREGROUND:
5714 ProcessFocusWhenForeground(sceneSession);
5715 if (!IsSessionVisibleForeground(sceneSession)) {
5716 sceneSession->SetPostProcessProperty(true);
5717 break;
5718 }
5719 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
5720 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
5721 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
5722 UpdatePrivateStateAndNotify(persistentId);
5723 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5724 ProcessSubSessionForeground(sceneSession);
5725 }
5726 break;
5727 case SessionState::STATE_BACKGROUND:
5728 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
5729 RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
5730 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
5731 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
5732 HandleKeepScreenOn(sceneSession, false);
5733 UpdatePrivateStateAndNotify(persistentId);
5734 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5735 ProcessSubSessionBackground(sceneSession);
5736 }
5737 break;
5738 case SessionState::STATE_CONNECT:
5739 SetSessionSnapshotSkipForAppProcess(sceneSession);
5740 SetSessionSnapshotSkipForAppBundleName(sceneSession);
5741 SetSessionWatermarkForAppProcess(sceneSession);
5742 break;
5743 case SessionState::STATE_DISCONNECT:
5744 if (SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
5745 RemoveProcessSnapshotSkip(sceneSession->GetCallingPid());
5746 RemoveProcessWatermarkPid(sceneSession->GetCallingPid());
5747 }
5748 break;
5749 default:
5750 break;
5751 }
5752 ProcessWindowModeType();
5753 }
5754
ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)5755 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
5756 {
5757 auto persistentId = sceneSession->GetPersistentId();
5758 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5759 persistentId == focusedSessionId_) {
5760 if (needBlockNotifyFocusStatusUntilForeground_) {
5761 needBlockNotifyUnfocusStatus_ = false;
5762 needBlockNotifyFocusStatusUntilForeground_ = false;
5763 NotifyFocusStatus(sceneSession, true);
5764 }
5765 } else if (!sceneSession->IsFocusedOnShow()) {
5766 sceneSession->SetFocusedOnShow(true);
5767 } else {
5768 if (Session::IsScbCoreEnabled()) {
5769 ProcessFocusWhenForegroundScbCore(sceneSession);
5770 } else {
5771 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5772 }
5773 }
5774 }
5775
ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)5776 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
5777 {
5778 if (IsSessionVisibleForeground(sceneSession)) {
5779 if (sceneSession->IsFocusableOnShow()) {
5780 RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
5781 } else {
5782 sceneSession->SetFocusableOnShow(true);
5783 }
5784 } else {
5785 PostProcessFocusState state = {true, true, true, FocusChangeReason::APP_FOREGROUND};
5786 sceneSession->SetPostProcessFocusState(state);
5787 }
5788 }
5789
ProcessWindowModeType()5790 void SceneSessionManager::ProcessWindowModeType()
5791 {
5792 if (isScreenLocked_) {
5793 return;
5794 }
5795 NotifyRSSWindowModeTypeUpdate();
5796 }
5797
IsSmallFoldProduct()5798 static bool IsSmallFoldProduct()
5799 {
5800 static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
5801 if (foldScreenType.empty()) {
5802 TLOGE(WmsLogTag::DEFAULT, "foldScreenType is empty");
5803 return false;
5804 }
5805 return foldScreenType[0] == '2';
5806 }
5807
IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)5808 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
5809 {
5810 auto sessionProperty = sceneSession->GetSessionProperty();
5811 if (sessionProperty == nullptr) {
5812 TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
5813 return false;
5814 }
5815 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
5816 return sessionProperty->GetDisplayId() != defaultScreenId;
5817 }
5818
CheckWindowModeType()5819 WindowModeType SceneSessionManager::CheckWindowModeType()
5820 {
5821 bool inSplit = false;
5822 bool inFloating = false;
5823 bool fullScreen = false;
5824 bool isSmallFold = IsSmallFoldProduct();
5825 {
5826 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5827 for (const auto& session : sceneSessionMap_) {
5828 if (session.second == nullptr ||
5829 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
5830 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
5831 continue;
5832 }
5833 if (isSmallFold && IsInSecondaryScreen(session.second)) {
5834 continue;
5835 }
5836 auto mode = session.second->GetWindowMode();
5837 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
5838 inSplit = true;
5839 }
5840 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
5841 inFloating = true;
5842 }
5843 if (WindowHelper::IsFullScreenWindow(mode)) {
5844 fullScreen = true;
5845 }
5846 }
5847 }
5848
5849 WindowModeType type;
5850 if (inSplit) {
5851 if (inFloating) {
5852 type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
5853 } else {
5854 type = WindowModeType::WINDOW_MODE_SPLIT;
5855 }
5856 } else {
5857 if (inFloating) {
5858 if (fullScreen) {
5859 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
5860 } else {
5861 type = WindowModeType::WINDOW_MODE_FLOATING;
5862 }
5863 } else if (fullScreen) {
5864 type = WindowModeType::WINDOW_MODE_FULLSCREEN;
5865 } else {
5866 type = WindowModeType::WINDOW_MODE_OTHER;
5867 }
5868 }
5869 return type;
5870 }
5871
NotifyRSSWindowModeTypeUpdate()5872 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
5873 {
5874 WindowModeType type = CheckWindowModeType();
5875 if (lastWindowModeType_ == type) {
5876 return;
5877 }
5878 lastWindowModeType_ = type;
5879 TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
5880 static_cast<uint8_t>(type));
5881 SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
5882 }
5883
ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)5884 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
5885 {
5886 if (sceneSession == nullptr) {
5887 WLOGFD("session is nullptr");
5888 return;
5889 }
5890 std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
5891 for (const auto& subSession : sceneSession->GetSubSession()) {
5892 if (subSession == nullptr) {
5893 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
5894 continue;
5895 }
5896 if (subSession->IsTopmost()) {
5897 modalVec.push_back(subSession);
5898 TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
5899 continue;
5900 }
5901 const auto& state = subSession->GetSessionState();
5902 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5903 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
5904 continue;
5905 }
5906 RequestSessionFocus(subSession->GetPersistentId(), true);
5907 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5908 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
5909 }
5910
5911 for (const auto& modal : modalVec) {
5912 if (modal == nullptr) {
5913 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
5914 continue;
5915 }
5916 const auto& state = modal->GetSessionState();
5917 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
5918 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
5919 continue;
5920 }
5921 auto modalSession = GetSceneSession(modal->GetPersistentId());
5922 if (modalSession == nullptr) {
5923 TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
5924 continue;
5925 }
5926 NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
5927 if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
5928 needBlockNotifyUnfocusStatus_ = false;
5929 needBlockNotifyFocusStatusUntilForeground_ = false;
5930 NotifyFocusStatus(modalSession, true);
5931 }
5932 HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
5933 }
5934 }
5935
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)5936 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5937 {
5938 // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
5939 sptr<SceneSession> mainSession = nullptr;
5940 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5941 mainSession = sceneSession;
5942 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5943 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5944 }
5945 if (mainSession == nullptr) {
5946 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5947 return WSError::WS_DO_NOTHING;
5948 }
5949
5950 std::vector<sptr<SceneSession>> topmostVec;
5951 for (auto subSession : mainSession->GetSubSession()) {
5952 if (subSession && subSession->IsTopmost()) {
5953 topmostVec.push_back(subSession);
5954 }
5955 }
5956 if (std::find_if(topmostVec.begin(), topmostVec.end(),
5957 [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5958 != topmostVec.end()) {
5959 TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
5960 return WSError::WS_OK;
5961 }
5962 WSError ret = WSError::WS_DO_NOTHING;
5963 for (auto topmostSession : topmostVec) {
5964 if (topmostSession == nullptr) {
5965 continue;
5966 }
5967 // no need to consider order, since rule of zOrder
5968 if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
5969 ret = WSError::WS_OK;
5970 }
5971 }
5972 return ret;
5973 }
5974
ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)5975 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5976 {
5977 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
5978 sptr<SceneSession> mainSession = nullptr;
5979 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5980 mainSession = sceneSession;
5981 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
5982 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
5983 }
5984 if (mainSession == nullptr) {
5985 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
5986 return WSError::WS_DO_NOTHING;
5987 }
5988 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
5989 if (std::find_if(dialogVec.begin(), dialogVec.end(),
5990 [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
5991 != dialogVec.end()) {
5992 TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
5993 return WSError::WS_OK;
5994 }
5995 WSError ret = WSError::WS_DO_NOTHING;
5996 for (auto dialog : dialogVec) {
5997 if (dialog == nullptr) {
5998 continue;
5999 }
6000 // no need to consider order, since rule of zOrder
6001 if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
6002 ret = WSError::WS_OK;
6003 }
6004 }
6005 return ret;
6006 }
6007
ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)6008 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
6009 {
6010 if (sceneSession == nullptr) {
6011 WLOGFD("session is nullptr");
6012 return;
6013 }
6014 for (const auto& subSession : sceneSession->GetSubSession()) {
6015 if (subSession == nullptr) {
6016 WLOGFD("sub session is nullptr");
6017 continue;
6018 }
6019 const auto& state = subSession->GetSessionState();
6020 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6021 WLOGFD("sub session is not active");
6022 continue;
6023 }
6024 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6025 HandleKeepScreenOn(subSession, false);
6026 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
6027 }
6028 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
6029 for (const auto& dialog : dialogVec) {
6030 if (dialog == nullptr) {
6031 TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
6032 continue;
6033 }
6034 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
6035 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6036 HandleKeepScreenOn(dialogSession, false);
6037 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
6038 }
6039 for (const auto& toastSession : sceneSession->GetToastSession()) {
6040 if (toastSession == nullptr) {
6041 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
6042 continue;
6043 }
6044 const auto& state = toastSession->GetSessionState();
6045 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6046 TLOGD(WmsLogTag::WMS_TOAST, "toast session is not active");
6047 continue;
6048 }
6049 NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6050 HandleKeepScreenOn(toastSession, false);
6051 UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
6052 toastSession->SetActive(false);
6053 toastSession->BackgroundTask();
6054 }
6055 }
6056
SetWindowFlags(const sptr<SceneSession>& sceneSession, const sptr<WindowSessionProperty>& property)6057 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
6058 const sptr<WindowSessionProperty>& property)
6059 {
6060 if (sceneSession == nullptr) {
6061 WLOGFD("session is nullptr");
6062 return WSError::WS_ERROR_NULLPTR;
6063 }
6064 auto sessionProperty = sceneSession->GetSessionProperty();
6065 if (sessionProperty == nullptr) {
6066 return WSError::WS_ERROR_NULLPTR;
6067 }
6068 uint32_t flags = property->GetWindowFlags();
6069 uint32_t oldFlags = sessionProperty->GetWindowFlags();
6070 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6071 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6072 !property->GetSystemCalling()) {
6073 WLOGFE("Set window flags permission denied");
6074 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6075 }
6076 sessionProperty->SetWindowFlags(flags);
6077 CheckAndNotifyWaterMarkChangedResult();
6078 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6079 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6080 }
6081 WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
6082 return WSError::WS_OK;
6083 }
6084
CheckAndNotifyWaterMarkChangedResult()6085 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
6086 {
6087 bool currentWaterMarkShowState = false;
6088 {
6089 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6090 for (const auto& iter: sceneSessionMap_) {
6091 auto& session = iter.second;
6092 if (!session) {
6093 continue;
6094 }
6095 auto sessionProperty = session->GetSessionProperty();
6096 if (!sessionProperty) {
6097 continue;
6098 }
6099 bool hasWaterMark = sessionProperty->GetWindowFlags() &
6100 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
6101 bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
6102 if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
6103 currentWaterMarkShowState = true;
6104 break;
6105 }
6106 }
6107 if (combinedExtWindowFlags_.waterMarkFlag) {
6108 TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
6109 currentWaterMarkShowState = true;
6110 }
6111 }
6112 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
6113 lastWaterMarkShowState_ = currentWaterMarkShowState;
6114 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
6115 }
6116 }
6117
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)6118 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
6119 {
6120 WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
6121 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
6122 return WSError::WS_OK;
6123 }
6124
ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const6125 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
6126 {
6127 if (!bundleMgr_) {
6128 WLOGFE("bundle manager is nullptr.");
6129 return;
6130 }
6131
6132 AAFwk::Want want;
6133 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
6134 auto uid = abilityInfo.uid;
6135 want.SetParam("uid", uid);
6136 bundleMgr_->ProcessPreload(want);
6137 }
6138
NotifyCompleteFirstFrameDrawing(int32_t persistentId)6139 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
6140 {
6141 auto scnSession = GetSceneSession(persistentId);
6142 if (scnSession == nullptr) {
6143 TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
6144 return;
6145 }
6146
6147 const auto& sessionInfo = scnSession->GetSessionInfo();
6148 if (IsAtomicServiceFreeInstall(sessionInfo)) {
6149 TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
6150 scnSession->GetPersistentId(), scnSession->GetWindowType());
6151 FillSessionInfo(scnSession);
6152 }
6153
6154 TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
6155 scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
6156 sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6157 auto abilityInfoPtr = sessionInfo.abilityInfo;
6158 if (abilityInfoPtr == nullptr) {
6159 TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is null, Id: %{public}d", persistentId);
6160 return;
6161 }
6162
6163 [this, persistentId] {
6164 auto task = [persistentId] {
6165 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6166 };
6167 WLOGI("Post CompleteFirstFrameDrawing task. Id: %{public}d", persistentId);
6168 eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6169 }();
6170
6171 auto task = [this, abilityInfoPtr, scnSession, persistentId] {
6172 if (!scnSession->GetSessionInfo().isSystem_ && !(abilityInfoPtr->excludeFromMissions)) {
6173 WLOGD("NotifyCreated, id: %{public}d", persistentId);
6174 listenerController_->NotifySessionCreated(persistentId);
6175 }
6176 ProcessPreload(*abilityInfoPtr);
6177 };
6178 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6179 }
6180
NotifySessionMovedToFront(int32_t persistentId)6181 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6182 {
6183 auto sceneSession = GetSceneSession(persistentId);
6184 if (sceneSession == nullptr) {
6185 WLOGFE("session is invalid with %{public}d", persistentId);
6186 return;
6187 }
6188 WLOGFI("id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6189 sceneSession->GetSessionInfo().isSystem_);
6190 if (!sceneSession->GetSessionInfo().isSystem_ &&
6191 sceneSession->GetSessionInfo().abilityInfo &&
6192 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6193 listenerController_->NotifySessionMovedToFront(persistentId);
6194 }
6195 }
6196
SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)6197 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6198 {
6199 WLOGFI("label: %{public}s", label.c_str());
6200 auto task = [this, &token, &label]() {
6201 auto sceneSession = FindSessionByToken(token);
6202 if (sceneSession == nullptr) {
6203 WLOGFI("fail to find session by token");
6204 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6205 }
6206 sceneSession->SetSessionLabel(label);
6207 WLOGI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6208 sceneSession->GetSessionInfo().isSystem_);
6209 if (!sceneSession->GetSessionInfo().isSystem_) {
6210 WLOGD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6211 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6212 }
6213 return WSError::WS_OK;
6214 };
6215 return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6216 }
6217
SetSessionIcon(const sptr<IRemoteObject>& token, const std::shared_ptr<Media::PixelMap>& icon)6218 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6219 const std::shared_ptr<Media::PixelMap>& icon)
6220 {
6221 WLOGFI("Enter");
6222 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6223 WLOGFE("The caller is not system-app, can not use system-api");
6224 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6225 }
6226
6227 auto task = [this, &token, &icon]() {
6228 auto sceneSession = FindSessionByToken(token);
6229 if (sceneSession == nullptr) {
6230 WLOGFI("fail to find session by token");
6231 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6232 }
6233 sceneSession->SetSessionIcon(icon);
6234 WLOGI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6235 sceneSession->GetSessionInfo().isSystem_);
6236 if (!sceneSession->GetSessionInfo().isSystem_ &&
6237 sceneSession->GetSessionInfo().abilityInfo &&
6238 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6239 WLOGD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6240 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6241 }
6242 return WSError::WS_OK;
6243 };
6244 return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6245 }
6246
IsValidSessionIds( const std::vector<int32_t>& sessionIds, std::vector<bool>& results)6247 WSError SceneSessionManager::IsValidSessionIds(
6248 const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6249 {
6250 WLOGFI("Enter");
6251 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6252 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6253 auto search = sceneSessionMap_.find(sessionIds.at(i));
6254 if (search == sceneSessionMap_.end() || search->second == nullptr) {
6255 results.push_back(false);
6256 continue;
6257 }
6258 results.push_back(true);
6259 }
6260 return WSError::WS_OK;
6261 }
6262
RegisterSessionListener(const sptr<ISessionListener>& listener)6263 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6264 {
6265 WLOGFI("in");
6266 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6267 WLOGFE("not system-app, can not use system-api");
6268 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6269 }
6270 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6271 TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
6272 return WSError::WS_ERROR_INVALID_PERMISSION;
6273 }
6274 auto task = [this, &listener] {
6275 WSError ret = listenerController_->AddSessionListener(listener);
6276 // app continue report for distributed scheduled service
6277 SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6278 static_cast<int32_t>(ret));
6279 return ret;
6280 };
6281 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6282 }
6283
UnRegisterSessionListener(const sptr<ISessionListener>& listener)6284 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6285 {
6286 WLOGFI("in");
6287 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6288 WLOGFE("not system-app, can not use system-api");
6289 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6290 }
6291 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6292 TLOGE(WmsLogTag::WMS_LIFE, "permission denied");
6293 return WSError::WS_ERROR_INVALID_PERMISSION;
6294 }
6295 auto task = [this, &listener] {
6296 listenerController_->DelSessionListener(listener);
6297 return WSError::WS_OK;
6298 };
6299 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6300 }
6301
GetSessionInfos(const std::string& deviceId, int32_t numMax, std::vector<SessionInfoBean>& sessionInfos)6302 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6303 std::vector<SessionInfoBean>& sessionInfos)
6304 {
6305 WLOGFI("Enter num max %{public}d", numMax);
6306 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6307 WLOGFE("The caller is not system-app, can not use system-api");
6308 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6309 }
6310 if (!SessionPermission::VerifySessionPermission()) {
6311 WLOGFE("The caller has not permission granted");
6312 return WSError::WS_ERROR_INVALID_PERMISSION;
6313 }
6314 auto task = [this, &deviceId, numMax, &sessionInfos]() {
6315 if (CheckIsRemote(deviceId)) {
6316 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6317 if (ret != ERR_OK) {
6318 return WSError::WS_ERROR_INVALID_PARAM;
6319 } else {
6320 return WSError::WS_OK;
6321 }
6322 }
6323 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6324 std::vector<sptr<SceneSession>> sceneSessionInfos;
6325 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6326 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6327 auto sceneSession = iter->second;
6328 if (sceneSession == nullptr) {
6329 WLOGFE("session is nullptr");
6330 continue;
6331 }
6332 auto sessionInfo = sceneSession->GetSessionInfo();
6333 if (sessionInfo.isSystem_) {
6334 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
6335 continue;
6336 }
6337 auto want = sessionInfo.want;
6338 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
6339 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6340 sceneSession->GetPersistentId());
6341 continue;
6342 }
6343 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
6344 break;
6345 }
6346 WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
6347 sessionInfo.bundleName_.c_str());
6348 sceneSessionInfos.emplace_back(sceneSession);
6349 }
6350 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
6351 };
6352 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
6353 }
6354
GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)6355 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
6356 {
6357 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
6358 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
6359 TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
6360 return WSError::WS_ERROR_INVALID_PERMISSION;
6361 }
6362 if (pid < 0) {
6363 return WSError::WS_ERROR_INVALID_PARAM;
6364 }
6365 auto task = [this, pid, &windowStates] {
6366 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6367 for (const auto& [_, sceneSession] : sceneSessionMap_) {
6368 if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
6369 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6370 MainWindowState windowState;
6371 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
6372 windowState.isVisible_ = sceneSession->GetRSVisible();
6373 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
6374 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
6375 windowStates.emplace_back(windowState);
6376 }
6377 }
6378 return WSError::WS_OK;
6379 };
6380 return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
6381 }
6382
GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax, std::vector<SessionInfoBean>& sessionInfos)6383 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
6384 std::vector<SessionInfoBean>& sessionInfos)
6385 {
6386 TLOGI(WmsLogTag::DEFAULT, "begin");
6387 int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
6388 if (result != ERR_OK) {
6389 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6390 return result;
6391 }
6392 return ERR_OK;
6393 }
6394
GetSessionInfo(const std::string& deviceId, int32_t persistentId, SessionInfoBean& sessionInfo)6395 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
6396 int32_t persistentId, SessionInfoBean& sessionInfo)
6397 {
6398 WLOGFI("id %{public}d", persistentId);
6399 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6400 WLOGFE("The caller is not system-app, can not use system-api");
6401 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6402 }
6403 if (!SessionPermission::VerifySessionPermission()) {
6404 WLOGFE("The caller has not permission granted");
6405 return WSError::WS_ERROR_INVALID_PERMISSION;
6406 }
6407 auto task = [this, &deviceId, persistentId, &sessionInfo]() {
6408 if (CheckIsRemote(deviceId)) {
6409 int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
6410 if (ret != ERR_OK) {
6411 return WSError::WS_ERROR_INVALID_PARAM;
6412 } else {
6413 return WSError::WS_OK;
6414 }
6415 }
6416 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6417 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6418 iter = sceneSessionMap_.find(persistentId);
6419 if (iter != sceneSessionMap_.end()) {
6420 auto sceneSession = iter->second;
6421 if (sceneSession == nullptr) {
6422 WLOGFE("session: %{public}d is nullptr", persistentId);
6423 return WSError::WS_ERROR_INVALID_PARAM;
6424 }
6425 auto sceneSessionInfo = sceneSession->GetSessionInfo();
6426 if (sceneSessionInfo.isSystem_) {
6427 WLOGFD("sessionId: %{public}d isSystemScene", persistentId);
6428 return WSError::WS_ERROR_INVALID_PARAM;
6429 }
6430 auto want = sceneSessionInfo.want;
6431 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
6432 want->GetElement().GetBundleName().empty()) {
6433 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6434 persistentId);
6435 return WSError::WS_ERROR_INTERNAL_ERROR;
6436 }
6437 WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
6438 sceneSessionInfo.bundleName_.c_str());
6439 return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
6440 } else {
6441 WLOGFW("sessionId: %{public}d not found", persistentId);
6442 return WSError::WS_ERROR_INVALID_PARAM;
6443 }
6444 };
6445 return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
6446 }
6447
GetSessionInfoByContinueSessionId(const std::string& continueSessionId, SessionInfoBean& sessionInfo)6448 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
6449 SessionInfoBean& sessionInfo)
6450 {
6451 TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
6452 continueSessionId.c_str());
6453 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6454 TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
6455 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6456 }
6457 if (!SessionPermission::VerifySessionPermission()) {
6458 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
6459 return WSError::WS_ERROR_INVALID_PERMISSION;
6460 }
6461 auto task = [this, continueSessionId, &sessionInfo]() {
6462 WSError ret = WSError::WS_ERROR_INVALID_SESSION;
6463 {
6464 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6465 for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
6466 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
6467 ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
6468 break;
6469 }
6470 }
6471 }
6472
6473 TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
6474 // app continue report for distributed scheduled service
6475 SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
6476 static_cast<int32_t>(ret));
6477 return ret;
6478 };
6479 return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
6480 }
6481
GetRemoteSessionInfo(const std::string& deviceId, int32_t persistentId, SessionInfoBean& sessionInfo)6482 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
6483 int32_t persistentId, SessionInfoBean& sessionInfo)
6484 {
6485 WLOGFI("GetRemoteSessionInfoFromDms begin");
6486 std::vector<SessionInfoBean> sessionVector;
6487 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
6488 if (result != ERR_OK) {
6489 return result;
6490 }
6491 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
6492 if (iter->id == persistentId) {
6493 sessionInfo = *iter;
6494 return ERR_OK;
6495 }
6496 }
6497 WLOGFW("missionId not found");
6498 return ERR_INVALID_VALUE;
6499 }
6500
CheckIsRemote(const std::string& deviceId)6501 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
6502 {
6503 if (deviceId.empty()) {
6504 WLOGFI("CheckIsRemote: deviceId is empty.");
6505 return false;
6506 }
6507 std::string localDeviceId;
6508 if (!GetLocalDeviceId(localDeviceId)) {
6509 WLOGFE("CheckIsRemote: get local deviceId failed");
6510 return false;
6511 }
6512 if (localDeviceId == deviceId) {
6513 WLOGFI("CheckIsRemote: deviceId is local.");
6514 return false;
6515 }
6516 WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
6517 return true;
6518 }
6519
GetLocalDeviceId(std::string& localDeviceId)6520 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
6521 {
6522 auto localNode = std::make_unique<NodeBasicInfo>();
6523 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
6524 if (errCode != ERR_OK) {
6525 WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
6526 return false;
6527 }
6528 if (localNode != nullptr) {
6529 localDeviceId = localNode->networkId;
6530 WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
6531 return true;
6532 }
6533 WLOGFE("localDeviceId null");
6534 return false;
6535 }
6536
AnonymizeDeviceId(const std::string& deviceId)6537 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
6538 {
6539 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
6540 return EMPTY_DEVICE_ID;
6541 }
6542 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
6543 anonDeviceId.append("******");
6544 return anonDeviceId;
6545 }
6546
DumpSessionAll(std::vector<std::string>& infos)6547 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
6548 {
6549 WLOGFI("Dump all session.");
6550 if (!SessionPermission::IsSystemCalling()) {
6551 WLOGFE("DumpSessionAll permission denied!");
6552 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6553 }
6554
6555 auto task = [this, &infos]() {
6556 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6557 infos.push_back(dumpInfo);
6558 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6559 for (const auto &item : sceneSessionMap_) {
6560 auto& session = item.second;
6561 if (session) {
6562 session->DumpSessionInfo(infos);
6563 }
6564 }
6565 return WSError::WS_OK;
6566 };
6567
6568 return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
6569 }
6570
DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)6571 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
6572 {
6573 WLOGFI("Dump session with id %{public}d", persistentId);
6574 if (!SessionPermission::IsSystemCalling()) {
6575 WLOGFE("DumpSessionWithId permission denied!");
6576 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6577 }
6578
6579 auto task = [this, persistentId, &infos]() {
6580 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6581 infos.push_back(dumpInfo);
6582 auto session = GetSceneSession(persistentId);
6583 if (session) {
6584 session->DumpSessionInfo(infos);
6585 } else {
6586 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
6587 }
6588 return WSError::WS_OK;
6589 };
6590
6591 return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
6592 }
6593
GetAllAbilityInfos( const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)6594 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
6595 const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6596 {
6597 if (bundleMgr_ == nullptr) {
6598 WLOGFE("bundleMgr_ is nullptr");
6599 return WSError::WS_ERROR_NULLPTR;
6600 }
6601 auto elementName = want.GetElement();
6602 int32_t ret{0};
6603 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6604 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6605 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6606 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6607 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6608 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6609 std::vector<AppExecFwk::BundleInfo> bundleInfos;
6610 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
6611 WLOGFD("want is empty queryAllAbilityInfos");
6612 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
6613 if (ret) {
6614 WLOGFE("Query all ability infos from BMS failed!");
6615 return WSError::WS_ERROR_INVALID_PARAM;
6616 }
6617 } else if (!elementName.GetBundleName().empty()) {
6618 AppExecFwk::BundleInfo bundleInfo;
6619 WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
6620 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
6621 if (ret) {
6622 WLOGFE("Query ability info from BMS failed!");
6623 return WSError::WS_ERROR_INVALID_PARAM;
6624 }
6625 bundleInfos.push_back(bundleInfo);
6626 } else {
6627 WLOGFE("invalid want:%{public}s", want.ToString().c_str());
6628 return WSError::WS_ERROR_INVALID_PARAM;
6629 }
6630 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6631 }
6632
GetBatchAbilityInfos( const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)6633 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
6634 const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6635 {
6636 if (bundleMgr_ == nullptr) {
6637 TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
6638 return WSError::WS_ERROR_NULLPTR;
6639 }
6640 if (bundleNames.empty()) {
6641 TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
6642 return WSError::WS_ERROR_INVALID_PARAM;
6643 }
6644 auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6645 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6646 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6647 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6648 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6649 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
6650 std::vector<AppExecFwk::BundleInfo> bundleInfos;
6651 auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
6652 if (ret) {
6653 TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
6654 return WSError::WS_ERROR_INVALID_PARAM;
6655 }
6656 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6657 }
6658
GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo>& bundleInfos, std::vector<SCBAbilityInfo>& scbAbilityInfos)6659 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo>& bundleInfos,
6660 std::vector<SCBAbilityInfo>& scbAbilityInfos)
6661 {
6662 if (bundleInfos.empty()) {
6663 WLOGFE("bundleInfos is empty");
6664 return WSError::WS_ERROR_INVALID_PARAM;
6665 }
6666 for (auto bundleInfo: bundleInfos) {
6667 auto hapModulesList = bundleInfo.hapModuleInfos;
6668 auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
6669 if (hapModulesList.empty()) {
6670 WLOGFD("hapModulesList is empty");
6671 continue;
6672 }
6673 for (auto hapModule: hapModulesList) {
6674 auto abilityInfoList = hapModule.abilityInfos;
6675 for (auto abilityInfo : abilityInfoList) {
6676 SCBAbilityInfo scbAbilityInfo;
6677 scbAbilityInfo.abilityInfo_ = abilityInfo;
6678 scbAbilityInfo.sdkVersion_ = sdkVersion;
6679 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6680 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6681 scbAbilityInfos.push_back(scbAbilityInfo);
6682 }
6683 }
6684 }
6685 return WSError::WS_OK;
6686 }
6687
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)6688 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
6689 {
6690 if (abilityInfo.orientationId == 0) {
6691 return;
6692 }
6693 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
6694 if (resConfig == nullptr) {
6695 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
6696 return;
6697 }
6698 std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
6699 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
6700 if (resourceMgr == nullptr) {
6701 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
6702 return;
6703 }
6704 std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
6705 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
6706 TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
6707 }
6708 std::string orientation;
6709 auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
6710 if (ret != Global::Resource::RState::SUCCESS) {
6711 TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
6712 static_cast<int32_t>(ret), abilityInfo.orientationId);
6713 return;
6714 }
6715 if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
6716 TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
6717 return;
6718 }
6719 abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
6720 }
6721
TerminateSessionNew( const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)6722 WSError SceneSessionManager::TerminateSessionNew(
6723 const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
6724 {
6725 if (info == nullptr) {
6726 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
6727 return WSError::WS_ERROR_INVALID_PARAM;
6728 }
6729 TLOGI(WmsLogTag::WMS_LIFE,
6730 "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
6731 info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
6732 int32_t callingPid = IPCSkeleton::GetCallingPid();
6733 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
6734 auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
6735 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
6736 if (sceneSession == nullptr) {
6737 TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
6738 return WSError::WS_ERROR_INVALID_PARAM;
6739 }
6740 const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
6741 if (!pidCheck &&
6742 !SessionPermission::VerifyPermissionByCallerToken(callerToken,
6743 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6744 TLOGE(WmsLogTag::WMS_LIFE,
6745 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
6746 sceneSession->GetCallingPid(), callingPid);
6747 return WSError::WS_ERROR_INVALID_PERMISSION;
6748 }
6749 WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
6750 return errCode;
6751 };
6752 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
6753 }
6754
SetVmaCacheStatus(bool flag)6755 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
6756 {
6757 WLOGFI("flag: %{public}d", flag);
6758 RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
6759 return WSError::WS_OK;
6760 }
6761
GetSessionSnapshot(const std::string& deviceId, int32_t persistentId, SessionSnapshot& snapshot, bool isLowResolution)6762 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
6763 SessionSnapshot& snapshot, bool isLowResolution)
6764 {
6765 WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
6766 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6767 WLOGFE("The caller is not system-app, can not use system-api");
6768 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6769 }
6770 if (!SessionPermission::VerifySessionPermission()) {
6771 WLOGFE("The caller has not permission granted");
6772 return WSError::WS_ERROR_INVALID_PERMISSION;
6773 }
6774 auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
6775 if (CheckIsRemote(deviceId)) {
6776 int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
6777 if (ret != ERR_OK) {
6778 return WSError::WS_ERROR_INVALID_PARAM;
6779 } else {
6780 return WSError::WS_OK;
6781 }
6782 }
6783 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6784 if (!sceneSession) {
6785 WLOGFE("fail to find session by persistentId: %{public}d", persistentId);
6786 return WSError::WS_ERROR_INVALID_PARAM;
6787 }
6788 auto sessionInfo = sceneSession->GetSessionInfo();
6789 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6790 WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6791 sceneSession->GetPersistentId());
6792 }
6793 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
6794 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
6795 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
6796 auto oriSnapshot = sceneSession->Snapshot();
6797 if (oriSnapshot != nullptr) {
6798 if (isLowResolution) {
6799 OHOS::Media::InitializationOptions options;
6800 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
6801 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
6802 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
6803 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
6804 } else {
6805 snapshot.snapshot = oriSnapshot;
6806 }
6807 }
6808 return WSError::WS_OK;
6809 };
6810 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
6811 }
6812
GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)6813 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
6814 {
6815 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
6816 TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
6817 return WMError::WM_ERROR_NOT_SYSTEM_APP;
6818 }
6819 auto task = [this, persistentId, &snapshot]() {
6820 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6821 if (!sceneSession) {
6822 TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
6823 return WMError::WM_ERROR_INVALID_PARAM;
6824 }
6825 auto sessionInfo = sceneSession->GetSessionInfo();
6826 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
6827 TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
6828 sceneSession->GetPersistentId());
6829 }
6830 snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
6831 snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
6832 snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
6833 auto oriSnapshot = sceneSession->Snapshot();
6834 if (oriSnapshot != nullptr) {
6835 snapshot.snapshot = oriSnapshot;
6836 return WMError::WM_OK;
6837 }
6838 return WMError::WM_ERROR_NULLPTR;
6839 };
6840 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
6841 }
6842
GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)6843 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
6844 {
6845 if (!SessionPermission::IsSACalling()) {
6846 TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
6847 return WSError::WS_ERROR_INVALID_PERMISSION;
6848 }
6849 TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
6850 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6851 if (sceneSession == nullptr) {
6852 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
6853 return WSError::WS_ERROR_NULLPTR;
6854 }
6855 return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
6856 }
6857
GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId, AAFwk::MissionSnapshot& sessionSnapshot)6858 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
6859 AAFwk::MissionSnapshot& sessionSnapshot)
6860 {
6861 TLOGI(WmsLogTag::DEFAULT, "begin");
6862 int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
6863 sessionId, sessionSnapshot);
6864 if (result != ERR_OK) {
6865 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6866 return result;
6867 }
6868 return ERR_OK;
6869 }
6870
GetCollaboratorByType(int32_t collaboratorType)6871 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
6872 {
6873 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
6874 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
6875 auto iter = collaboratorMap_.find(collaboratorType);
6876 if (iter == collaboratorMap_.end()) {
6877 TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
6878 return collaborator;
6879 }
6880 collaborator = iter->second;
6881 if (collaborator == nullptr) {
6882 TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
6883 }
6884 return collaborator;
6885 }
6886
RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)6887 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
6888 {
6889 wptr<SceneSession> weakSceneSession(sceneSession);
6890 auto task = [this, weakSceneSession]() {
6891 auto scnSession = weakSceneSession.promote();
6892 if (scnSession == nullptr) {
6893 WLOGFE("session is nullptr");
6894 return WSError::WS_ERROR_NULLPTR;
6895 }
6896 auto persistentId = scnSession->GetPersistentId();
6897 if (!GetSceneSession(persistentId)) {
6898 WLOGFE("session is invalid with %{public}d", persistentId);
6899 return WSError::WS_ERROR_INVALID_SESSION;
6900 }
6901 auto sessionInfo = scnSession->GetSessionInfo();
6902 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
6903 if (!abilitySessionInfo) {
6904 TLOGE(WmsLogTag::WMS_MAIN,
6905 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
6906 return WSError::WS_ERROR_NULLPTR;
6907 }
6908 if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
6909 scnSession->SetActive(false);
6910 } else if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::FOREGROUND)) {
6911 scnSession->SetActive(true);
6912 } else {
6913 WLOGFE("wrong callState_");
6914 }
6915 TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
6916 sessionInfo.callState_, persistentId);
6917 bool isColdStart = false;
6918 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
6919 if (isColdStart) {
6920 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
6921 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
6922 scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
6923 scnSession->ResetSessionConnectState();
6924 }
6925 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
6926 return WSError::WS_OK;
6927 };
6928 std::string taskName = "RequestSceneSessionByCall:PID:" +
6929 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
6930 taskScheduler_->PostAsyncTask(task, taskName);
6931 return WSError::WS_OK;
6932 }
6933
StartAbilityBySpecified(const SessionInfo& sessionInfo)6934 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
6935 {
6936 auto task = [this, sessionInfo]() {
6937 WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
6938 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6939 AAFwk::Want want;
6940 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
6941 if (sessionInfo.want != nullptr) {
6942 want.SetParams(sessionInfo.want->GetParams());
6943 want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast<int>(sessionInfo.screenId_));
6944 }
6945 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
6946 };
6947
6948 taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
6949 }
6950
NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)6951 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
6952 {
6953 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
6954 if (pid == -1) {
6955 TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
6956 return;
6957 }
6958 int32_t ret = HiSysEventWrite(
6959 HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
6960 "WINDOW_STATE_ERROR",
6961 HiviewDFX::HiSysEvent::EventType::FAULT,
6962 "PID", pid,
6963 "PERSISTENT_ID", persistentId);
6964 if (ret != 0) {
6965 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
6966 }
6967 auto task = [this, pid] {
6968 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6969 for (const auto& [_, sceneSession] : sceneSessionMap_) {
6970 if (!sceneSession || pid != sceneSession->GetCallingPid() ||
6971 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6972 continue;
6973 }
6974 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6975 if (abilitySessionInfo) {
6976 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
6977 abilitySessionInfo->persistentId);
6978 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
6979 }
6980 }
6981 };
6982 // delay 2000ms, wait for hidumper
6983 taskScheduler_->PostAsyncTask(task, __func__, 2000);
6984 }
6985
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)6986 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
6987 {
6988 if (!targetToken) {
6989 WLOGFE("Token is null, cannot find main window");
6990 return nullptr;
6991 }
6992
6993 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6994 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
6995 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
6996 if (pair.second->IsTerminated()) {
6997 return false;
6998 }
6999 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7000 return pair.second->GetAbilityToken() == targetToken;
7001 }
7002 return false;
7003 });
7004 if (iter == sceneSessionMap_.end()) {
7005 WLOGFE("Cannot find session");
7006 return nullptr;
7007 }
7008 return iter->second;
7009 }
7010
BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)7011 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
7012 {
7013 if (!SessionPermission::IsSystemCalling()) {
7014 TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
7015 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7016 }
7017 if (targetToken == nullptr) {
7018 TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
7019 return WSError::WS_ERROR_NULLPTR;
7020 }
7021
7022 auto task = [this, persistentId, targetToken]() {
7023 auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
7024 if (scnSession == nullptr) {
7025 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
7026 return WSError::WS_ERROR_NULLPTR;
7027 }
7028 if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
7029 TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
7030 return WSError::WS_OK;
7031 }
7032 scnSession->dialogTargetToken_ = targetToken;
7033 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
7034 if (parentSession == nullptr) {
7035 scnSession->NotifyDestroy();
7036 return WSError::WS_ERROR_INVALID_PARAM;
7037 }
7038 scnSession->SetParentSession(parentSession);
7039 scnSession->SetParentPersistentId(parentSession->GetPersistentId());
7040 UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
7041 TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
7042 persistentId, parentSession->GetPersistentId());
7043 return WSError::WS_OK;
7044 };
7045 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
7046 }
7047
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds, std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)7048 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7049 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7050 {
7051 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
7052 }
7053
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds, std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)7054 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7055 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7056 {
7057 auto isSaCall = SessionPermission::IsSACalling();
7058 if (!isSaCall) {
7059 WLOGFE("The interface only support for sa call");
7060 return WMError::WM_ERROR_INVALID_PERMISSION;
7061 }
7062 auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
7063 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7064 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7065 for (auto missionId : missionIds) {
7066 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
7067 if (iter == sceneSessionMap_.end()) {
7068 continue;
7069 }
7070 auto sceneSession = iter->second;
7071 if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
7072 continue;
7073 }
7074 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
7075 if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
7076 surfaceNodeIds.push_back(missionId);
7077 continue;
7078 }
7079 if (sceneSession->GetLeashWinSurfaceNode()) {
7080 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
7081 }
7082 }
7083 return WMError::WM_OK;
7084 };
7085 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
7086 }
7087
RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr<IWindowManagerAgent>& windowManagerAgent)7088 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
7089 const sptr<IWindowManagerAgent>& windowManagerAgent)
7090 {
7091 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7092 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7093 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7094 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7095 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE ||
7096 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_PID_VISIBILITY) {
7097 if (!SessionPermission::IsSACalling()) {
7098 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7099 return WMError::WM_ERROR_INVALID_PERMISSION;
7100 }
7101 }
7102 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
7103 TLOGD(WmsLogTag::DEFAULT, "permission denied");
7104 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7105 }
7106 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7107 WLOGFE("windowManagerAgent is null");
7108 return WMError::WM_ERROR_NULLPTR;
7109 }
7110 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7111 auto task = [this, windowManagerAgent, type, callingPid]() {
7112 return SessionManagerAgentController::GetInstance()
7113 .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7114 };
7115 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
7116 }
7117
UnregisterWindowManagerAgent(WindowManagerAgentType type, const sptr<IWindowManagerAgent>& windowManagerAgent)7118 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
7119 const sptr<IWindowManagerAgent>& windowManagerAgent)
7120 {
7121 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7122 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7123 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7124 if (!SessionPermission::IsSystemCalling()) {
7125 WLOGFE("UnregisterWindowManagerAgent permission denied!");
7126 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7127 }
7128 }
7129 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7130 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7131 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7132 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7133 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7134 if (!SessionPermission::IsSACalling()) {
7135 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7136 return WMError::WM_ERROR_INVALID_PERMISSION;
7137 }
7138 }
7139 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7140 WLOGFE("windowManagerAgent is null");
7141 return WMError::WM_ERROR_NULLPTR;
7142 }
7143 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7144 auto task = [this, windowManagerAgent, type, callingPid]() {
7145 return SessionManagerAgentController::GetInstance()
7146 .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7147 };
7148 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7149 }
7150
UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)7151 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7152 {
7153 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7154 }
7155
UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)7156 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7157 {
7158 SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7159 }
7160
StartWindowInfoReportLoop()7161 void SceneSessionManager::StartWindowInfoReportLoop()
7162 {
7163 WLOGFD("in");
7164 if (isReportTaskStart_) {
7165 WLOGFE("Report is ReportTask Start");
7166 return;
7167 }
7168 auto task = [this] {
7169 WindowInfoReporter::GetInstance().ReportRecordedInfos();
7170 ReportWindowProfileInfos();
7171 isReportTaskStart_ = false;
7172 StartWindowInfoReportLoop();
7173 };
7174 int64_t delayTime = 1000 * 60 * 60; // an hour.
7175 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7176 if (!ret) {
7177 WLOGFE("failed. task is WindowInfoReport");
7178 return;
7179 }
7180 isReportTaskStart_ = true;
7181 }
7182
InitPersistentStorage()7183 void SceneSessionManager::InitPersistentStorage()
7184 {
7185 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7186 int32_t storageMode = -1;
7187 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7188 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7189 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7190 WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7191 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7192 }
7193 }
7194 }
7195
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)7196 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7197 {
7198 WLOGFD("Called.");
7199 if (!SessionPermission::IsSystemServiceCalling()) {
7200 WLOGFE("Only support for system service.");
7201 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7202 }
7203 auto task = [this, &infos]() {
7204 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7205 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7206 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7207 sptr<SceneSession> sceneSession = iter->second;
7208 if (sceneSession == nullptr) {
7209 WLOGFW("null scene session");
7210 continue;
7211 }
7212 bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7213 sceneSession->IsVisibleForAccessibility() :
7214 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7215 WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7216 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7217 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7218 sceneSession->GetSessionState(), isVisibleForAccessibility);
7219 if (isVisibleForAccessibility) {
7220 FillWindowInfo(infos, iter->second);
7221 }
7222 }
7223 return WMError::WM_OK;
7224 };
7225 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7226 }
7227
CheckUnreliableWindowType(WindowType windowType)7228 static bool CheckUnreliableWindowType(WindowType windowType)
7229 {
7230 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7231 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7232 windowType == WindowType::WINDOW_TYPE_TOAST) {
7233 return true;
7234 }
7235 TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7236 return false;
7237 }
7238
FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession, std::vector<sptr<UnreliableWindowInfo>>& infos)7239 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7240 std::vector<sptr<UnreliableWindowInfo>>& infos)
7241 {
7242 if (sceneSession == nullptr) {
7243 TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7244 return;
7245 }
7246 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7247 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7248 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7249 TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7250 return;
7251 }
7252 sptr<UnreliableWindowInfo> info = sptr<UnreliableWindowInfo>::MakeSptr();
7253 info->windowId_ = sceneSession->GetPersistentId();
7254 WSRect windowRect = sceneSession->GetSessionRect();
7255 info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7256 info->zOrder_ = sceneSession->GetZOrder();
7257 info->floatingScale_ = sceneSession->GetFloatingScale();
7258 info->scaleX_ = sceneSession->GetScaleX();
7259 info->scaleY_ = sceneSession->GetScaleY();
7260 infos.emplace_back(info);
7261 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7262 }
7263
GetUnreliableWindowInfo(int32_t windowId, std::vector<sptr<UnreliableWindowInfo>>& infos)7264 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
7265 std::vector<sptr<UnreliableWindowInfo>>& infos)
7266 {
7267 TLOGD(WmsLogTag::DEFAULT, "Called.");
7268 if (!SessionPermission::IsSystemServiceCalling()) {
7269 TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
7270 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7271 }
7272 auto task = [this, windowId, &infos]() {
7273 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7274 for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
7275 if (sceneSession == nullptr) {
7276 TLOGW(WmsLogTag::DEFAULT, "null scene session");
7277 continue;
7278 }
7279 if (sessionId == windowId) {
7280 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
7281 FillUnreliableWindowInfo(sceneSession, infos);
7282 continue;
7283 }
7284 if (!sceneSession->GetRSVisible()) {
7285 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
7286 continue;
7287 }
7288 TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
7289 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
7290 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
7291 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
7292 if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
7293 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
7294 "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
7295 FillUnreliableWindowInfo(sceneSession, infos);
7296 }
7297 }
7298 return WMError::WM_OK;
7299 };
7300 return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
7301 }
7302
NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)7303 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
7304 {
7305 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
7306 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7307 if (sceneSession == nullptr) {
7308 WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
7309 return;
7310 }
7311 wptr<SceneSession> weakSceneSession(sceneSession);
7312 if (processingFlushUIParams_.load()) {
7313 TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
7314 auto task = [this, weakSceneSession, type]() {
7315 auto sceneSession = weakSceneSession.promote();
7316 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7317 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7318 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7319 }
7320 };
7321 taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
7322 return;
7323 }
7324 auto task = [this, weakSceneSession, type]() {
7325 auto sceneSession = weakSceneSession.promote();
7326 NotifyAllAccessibilityInfo();
7327 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7328 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7329 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7330 }
7331 };
7332 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
7333 auto notifySceneInputTask = [weakSceneSession, type]() {
7334 auto sceneSession = weakSceneSession.promote();
7335 if (sceneSession == nullptr) {
7336 return;
7337 }
7338 SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
7339 };
7340 taskScheduler_->PostAsyncTask(notifySceneInputTask);
7341 }
7342
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos, const sptr<SceneSession>& sceneSession)7343 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
7344 const sptr<SceneSession>& sceneSession)
7345 {
7346 if (sceneSession == nullptr) {
7347 WLOGFW("null scene session.");
7348 return false;
7349 }
7350 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7351 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7352 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7353 WLOGFD("filter gesture window.");
7354 return false;
7355 }
7356 sptr<AccessibilityWindowInfo> info = sptr<AccessibilityWindowInfo>::MakeSptr();
7357 if (sceneSession->GetSessionInfo().isSystem_) {
7358 info->wid_ = 1;
7359 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7360 } else {
7361 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7362 }
7363 info->uiNodeId_ = sceneSession->GetUINodeId();
7364 WSRect wsrect = sceneSession->GetSessionGlobalRect(); // only accessability and mmi need global
7365 info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
7366 info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
7367 info->type_ = sceneSession->GetWindowType();
7368 info->mode_ = sceneSession->GetWindowMode();
7369 info->layer_ = sceneSession->GetZOrder();
7370 info->scaleVal_ = sceneSession->GetFloatingScale();
7371 info->scaleX_ = sceneSession->GetScaleX();
7372 info->scaleY_ = sceneSession->GetScaleY();
7373 info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
7374 info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
7375 auto property = sceneSession->GetSessionProperty();
7376 if (property != nullptr) {
7377 info->displayId_ = property->GetDisplayId();
7378 info->isDecorEnable_ = property->IsDecorEnable();
7379 }
7380 infos.emplace_back(info);
7381 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
7382 info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
7383 return true;
7384 }
7385
GetSessionSnapshotFilePath(int32_t persistentId)7386 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
7387 {
7388 WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
7389 auto sceneSession = GetSceneSession(persistentId);
7390 if (sceneSession == nullptr) {
7391 WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
7392 return "";
7393 }
7394 wptr<SceneSession> weakSceneSession(sceneSession);
7395 auto task = [this, weakSceneSession]() {
7396 auto scnSession = weakSceneSession.promote();
7397 if (scnSession == nullptr) {
7398 WLOGFE("session is nullptr");
7399 return std::string("");
7400 }
7401 std::string filePath = scnSession->GetSessionSnapshotFilePath();
7402 return filePath;
7403 };
7404 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
7405 }
7406
SelectSesssionFromMap(const uint64_t& surfaceId)7407 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
7408 {
7409 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7410 for (const auto &item : sceneSessionMap_) {
7411 auto sceneSession = item.second;
7412 if (sceneSession == nullptr) {
7413 continue;
7414 }
7415 if (sceneSession->GetSurfaceNode() == nullptr) {
7416 continue;
7417 }
7418 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
7419 return sceneSession;
7420 }
7421 }
7422 return nullptr;
7423 }
7424
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)7425 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
7426 {
7427 WLOGFD("WindowLayerInfoChangeCallback: entry");
7428 std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
7429
7430 auto task = [this, weak]() {
7431 auto weakOcclusionData = weak.lock();
7432 if (weakOcclusionData == nullptr) {
7433 WLOGFE("weak occlusionData is nullptr");
7434 return;
7435 }
7436 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
7437 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
7438 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
7439 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
7440 if (currVisibleData.size() != 0) {
7441 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
7442 }
7443 if (visibilityChangeInfos.size() != 0) {
7444 DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
7445 CacVisibleWindowNum();
7446 }
7447
7448 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
7449 if (currDrawingContentData.size() != 0) {
7450 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
7451 }
7452 if (drawingContentChangeInfos.size() != 0) {
7453 DealwithDrawingContentChange(drawingContentChangeInfos);
7454 }
7455 };
7456 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
7457 }
7458
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData, std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData, std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)7459 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
7460 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
7461 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
7462 {
7463 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
7464 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
7465 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
7466 switch (windowLayerState) {
7467 case WINDOW_ALL_VISIBLE:
7468 case WINDOW_SEMI_VISIBLE:
7469 case WINDOW_IN_VISIBLE:
7470 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
7471 break;
7472 case WINDOW_LAYER_DRAWING:
7473 currDrawingContentData.emplace_back(iter->first, true);
7474 break;
7475 case WINDOW_LAYER_NO_DRAWING:
7476 currDrawingContentData.emplace_back(iter->first, false);
7477 break;
7478 default:
7479 break;
7480 }
7481 }
7482 }
7483
UpdateSubWindowVisibility(const sptr<SceneSession>& session, WindowVisibilityState visibleState, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7484 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
7485 WindowVisibilityState visibleState,
7486 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7487 std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
7488 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7489 {
7490 if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
7491 visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7492 auto subSessions = GetSubSceneSession(session->GetWindowId());
7493 if (subSessions.empty()) {
7494 return;
7495 }
7496
7497 RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
7498
7499 for (const auto& subSession : subSessions) {
7500 if (subSession == nullptr) {
7501 continue;
7502 }
7503 if (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData)) {
7504 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
7505 subSession->GetWindowId());
7506 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
7507 }
7508 }
7509 }
7510 }
7511
GetSessionRSVisible(const sptr<Session>& session, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7512 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
7513 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7514 {
7515 bool sessionRSVisible = false;
7516 for (const auto& [surfaceId, visibleState] : currVisibleData) {
7517 sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
7518 if (visibilitySession == nullptr) {
7519 continue;
7520 }
7521 if (session->GetWindowId() == visibilitySession->GetWindowId()) {
7522 if (visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7523 sessionRSVisible = true;
7524 }
7525 break;
7526 }
7527 }
7528 return sessionRSVisible;
7529 }
7530
SetSessionVisibilityInfo(const sptr<SceneSession>& session, WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo)7531 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
7532 WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
7533 std::string& visibilityInfo)
7534 {
7535 if (session == nullptr) {
7536 TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
7537 return;
7538 }
7539 session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7540 session->SetVisibilityState(visibleState);
7541 int32_t windowId = session->GetWindowId();
7542 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
7543 session->NotifyWindowVisibility();
7544 }
7545 windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
7546 windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
7547
7548 visibilityInfo +=
7549 "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
7550 }
7551
RemoveDuplicateSubSession( const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo, std::vector<sptr<SceneSession>>& subSessions)7552 void SceneSessionManager::RemoveDuplicateSubSession(
7553 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7554 std::vector<sptr<SceneSession>>& subSessions)
7555 {
7556 for (const auto& elem : visibilityChangeInfo) {
7557 uint64_t surfaceId = elem.first;
7558 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7559 if (session == nullptr) {
7560 continue;
7561 }
7562 for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
7563 auto subSession = *iterator;
7564 if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
7565 iterator = subSessions.erase(iterator);
7566 } else {
7567 ++iterator;
7568 }
7569 }
7570 }
7571 }
7572
GetSubSceneSession(int32_t parentWindowId)7573 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
7574 {
7575 std::vector<sptr<SceneSession>> subSessions;
7576 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7577 for (const auto& iter : sceneSessionMap_) {
7578 auto sceneSession = iter.second;
7579 if (sceneSession == nullptr) {
7580 continue;
7581 }
7582 if (sceneSession->GetParentSession() != nullptr &&
7583 sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
7584 subSessions.push_back(sceneSession);
7585 }
7586 }
7587 return subSessions;
7588 }
7589
GetWindowVisibilityChangeInfo( std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7590 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
7591 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7592 {
7593 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
7594 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
7595 uint32_t i, j;
7596 i = j = 0;
7597 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
7598 if (lastVisibleData_[i].first < currVisibleData[j].first) {
7599 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7600 i++;
7601 } else if (lastVisibleData_[i].first > currVisibleData[j].first &&
7602 currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7603 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7604 j++;
7605 } else {
7606 if (lastVisibleData_[i].second != currVisibleData[j].second) {
7607 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7608 }
7609 i++;
7610 j++;
7611 }
7612 }
7613 for (; i < lastVisibleData_.size(); ++i) {
7614 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7615 }
7616 for (; j < currVisibleData.size(); ++j) {
7617 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7618 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7619 }
7620 }
7621 lastVisibleData_ = currVisibleData;
7622 return visibilityChangeInfo;
7623 }
7624
DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)7625 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
7626 visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7627 {
7628 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7629 #ifdef MEMMGR_WINDOW_ENABLE
7630 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7631 #endif
7632
7633 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
7634 for (const auto& elem : visibilityChangeInfo) {
7635 uint64_t surfaceId = elem.first;
7636 WindowVisibilityState visibleState = elem.second;
7637 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7638 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7639 if (session == nullptr) {
7640 continue;
7641 }
7642 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
7643 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
7644 if (session->GetParentSession() != nullptr &&
7645 !session->GetParentSession()->IsSessionForeground() &&
7646 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
7647 continue;
7648 }
7649 }
7650 SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
7651 UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
7652 #ifdef MEMMGR_WINDOW_ENABLE
7653 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
7654 session->GetCallingUid(), isVisible));
7655 #endif
7656 CheckAndNotifyWaterMarkChangedResult();
7657 }
7658 if (windowVisibilityInfos.size() != 0) {
7659 WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
7660 visibilityInfo.c_str());
7661 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7662 }
7663 #ifdef MEMMGR_WINDOW_ENABLE
7664 if (memMgrWindowInfos.size() != 0) {
7665 WLOGD("Notify memMgrWindowInfos changed start");
7666 taskScheduler_ ->AddExportTask("notifyMemMgr", [memMgrWindowInfos = std::move(memMgrWindowInfos)]() {
7667 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7668 });
7669 }
7670 #endif
7671 }
7672
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>& drawingContentChangeInfo)7673 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
7674 drawingContentChangeInfo)
7675 {
7676 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
7677 for (const auto& elem : drawingContentChangeInfo) {
7678 uint64_t surfaceId = elem.first;
7679 bool drawingState = elem.second;
7680 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7681 if (session == nullptr) {
7682 continue;
7683 }
7684 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
7685 session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
7686 if (openDebugTrace_) {
7687 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
7688 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
7689 }
7690 WLOGFD("drawing status changed pid:%{public}d, "
7691 "surfaceId:%{public}" PRIu64 ", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
7692 }
7693 if (windowDrawingContenInfos.size() != 0) {
7694 WLOGFD("Notify WindowDrawingContenInfo changed start");
7695 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
7696 }
7697 }
7698
GetWindowDrawingContentChangeInfo( std::vector<std::pair<uint64_t, bool>> currDrawingContentData)7699 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
7700 std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
7701 {
7702 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
7703 for (const auto& data : currDrawingContentData) {
7704 uint64_t windowId = data.first;
7705 bool currentDrawingContentState = data.second;
7706 int32_t pid = 0;
7707 bool isChange = false;
7708 if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
7709 continue;
7710 } else {
7711 isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
7712 }
7713
7714 if (isChange) {
7715 processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
7716 }
7717 }
7718 return processDrawingContentChangeInfo;
7719 }
7720
GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)7721 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
7722 {
7723 bool preWindowDrawingState = true;
7724 sptr<SceneSession> session = SelectSesssionFromMap(windowId);
7725 if (session == nullptr) {
7726 return false;
7727 }
7728 pid = session->GetCallingPid();
7729 preWindowDrawingState = session->GetDrawingContentState();
7730 session->SetDrawingContentState(currentDrawingContentState);
7731 return preWindowDrawingState;
7732 }
7733
GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)7734 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
7735 {
7736 bool isChange = true;
7737 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7738 for (const auto& item : sceneSessionMap_) {
7739 auto sceneSession = item.second;
7740 if (sceneSession == nullptr) {
7741 continue;
7742 }
7743 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
7744 windowId != sceneSession->GetSurfaceNode()->GetId()) {
7745 if (sceneSession->GetDrawingContentState()) {
7746 return false;
7747 }
7748 }
7749 }
7750 return isChange;
7751 }
7752
7753
InitWithRenderServiceAdded()7754 void SceneSessionManager::InitWithRenderServiceAdded()
7755 {
7756 auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
7757 this->WindowLayerInfoChangeCallback(occlusiontionData);
7758 };
7759 WLOGI("RegisterWindowVisibilityChangeCallback");
7760 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
7761 WLOGFE("RegisterWindowVisibilityChangeCallback failed");
7762 }
7763 }
7764
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)7765 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
7766 {
7767 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
7768 WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
7769 return WMError::WM_ERROR_INVALID_PARAM;
7770 }
7771
7772 auto task = [this, sceneType]() {
7773 WLOGFD("Set system animated scene %{public}d.", sceneType);
7774 bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
7775 if (!ret) {
7776 WLOGFE("Set system animated scene failed.");
7777 }
7778 };
7779 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
7780 return WMError::WM_OK;
7781 }
7782
NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)7783 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
7784 {
7785 if (!SessionPermission::IsSystemCalling()) {
7786 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
7787 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7788 }
7789 if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
7790 TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
7791 return WSError::WS_ERROR_INVALID_PERMISSION;
7792 }
7793 TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
7794 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
7795 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7796 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
7797 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
7798 WindowType::WINDOW_TYPE_APP_COMPONENT));
7799 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7800 return WSError::WS_OK;
7801 }
7802
WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)7803 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
7804 {
7805 if (sceneSession == nullptr) {
7806 WLOGFE("sceneSession is nullptr!");
7807 return;
7808 }
7809 if (sceneSession->GetRSVisible()) {
7810 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7811 #ifdef MEMMGR_WINDOW_ENABLE
7812 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7813 #endif
7814 sceneSession->SetRSVisible(false);
7815 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7816 sceneSession->ClearExtWindowFlags();
7817 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
7818 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
7819 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
7820 #ifdef MEMMGR_WINDOW_ENABLE
7821 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
7822 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
7823 #endif
7824 WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
7825 sceneSession->GetWindowId(), sceneSession->GetRSVisible());
7826 CheckAndNotifyWaterMarkChangedResult();
7827 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7828 #ifdef MEMMGR_WINDOW_ENABLE
7829 WLOGD("Notify memMgrWindowInfos changed start");
7830 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
7831 #endif
7832 }
7833 }
7834
FindSessionByToken(const sptr<IRemoteObject>& token)7835 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
7836 {
7837 if (token == nullptr) {
7838 TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
7839 return nullptr;
7840 }
7841 sptr<SceneSession> session = nullptr;
7842 auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7843 if (pair.second == nullptr) {
7844 return false;
7845 }
7846 return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
7847 };
7848 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7849 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7850 if (iter != sceneSessionMap_.end()) {
7851 session = iter->second;
7852 }
7853 return session;
7854 }
7855
FindSessionByAffinity(std::string affinity)7856 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
7857 {
7858 if (affinity.size() == 0) {
7859 WLOGFI("AbilityInfo affinity is empty");
7860 return nullptr;
7861 }
7862 sptr<SceneSession> session = nullptr;
7863 auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7864 if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
7865 return false;
7866 }
7867 return pair.second->GetSessionInfo().sessionAffinity == affinity;
7868 };
7869 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7870 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
7871 if (iter != sceneSessionMap_.end()) {
7872 session = iter->second;
7873 }
7874 return session;
7875 }
7876
PreloadInLakeApp(const std::string& bundleName)7877 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
7878 {
7879 WLOGFD("Enter name %{public}s", bundleName.c_str());
7880 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
7881 if (collaborator != nullptr) {
7882 WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
7883 collaborator->NotifyPreloadAbility(bundleName);
7884 }
7885 }
7886
PendingSessionToForeground(const sptr<IRemoteObject>& token)7887 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
7888 {
7889 TLOGI(WmsLogTag::DEFAULT, "Enter");
7890 auto pid = IPCSkeleton::GetCallingRealPid();
7891 if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
7892 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
7893 return WSError::WS_ERROR_INVALID_PERMISSION;
7894 }
7895
7896 auto task = [this, &token]() {
7897 auto session = FindSessionByToken(token);
7898 if (session != nullptr) {
7899 return session->PendingSessionToForeground();
7900 }
7901 TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
7902 return WSError::WS_ERROR_INVALID_PARAM;
7903 };
7904 return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
7905 }
7906
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token, bool shouldBackToCaller)7907 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
7908 bool shouldBackToCaller)
7909 {
7910 auto task = [this, &token, shouldBackToCaller] {
7911 auto session = FindSessionByToken(token);
7912 if (session != nullptr) {
7913 return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
7914 }
7915 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
7916 return WSError::WS_ERROR_INVALID_PARAM;
7917 };
7918 return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
7919 }
7920
ClearDisplayStatusBarTemporarilyFlags()7921 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
7922 {
7923 for (auto persistentId : avoidAreaListenerSessionSet_) {
7924 auto sceneSession = GetSceneSession(persistentId);
7925 if (sceneSession == nullptr) {
7926 continue;
7927 }
7928 sceneSession->SetIsDisplayStatusBarTemporarily(false);
7929 }
7930 }
7931
GetFocusSessionToken(sptr<IRemoteObject>& token)7932 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject>& token)
7933 {
7934 if (!SessionPermission::IsSACalling()) {
7935 WLOGFE("GetFocusSessionToken permission denied!");
7936 return WSError::WS_ERROR_INVALID_PERMISSION;
7937 }
7938 auto task = [this, &token]() {
7939 WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
7940 auto sceneSession = GetSceneSession(focusedSessionId_);
7941 if (sceneSession) {
7942 token = sceneSession->GetAbilityToken();
7943 if (token == nullptr) {
7944 WLOGFE("token is nullptr");
7945 return WSError::WS_ERROR_INVALID_PARAM;
7946 }
7947 return WSError::WS_OK;
7948 }
7949 return WSError::WS_ERROR_INVALID_SESSION;
7950 };
7951 return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
7952 }
7953
GetFocusSessionElement(AppExecFwk::ElementName& element)7954 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
7955 {
7956 AppExecFwk::RunningProcessInfo info;
7957 auto pid = IPCSkeleton::GetCallingRealPid();
7958 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
7959 if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
7960 WLOGFE("SystemCalling permission denied!");
7961 return WSError::WS_ERROR_INVALID_PERMISSION;
7962 }
7963 auto task = [this, &element]() {
7964 WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
7965 auto sceneSession = GetSceneSession(focusedSessionId_);
7966 if (sceneSession) {
7967 auto sessionInfo = sceneSession->GetSessionInfo();
7968 element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
7969 sessionInfo.abilityName_, sessionInfo.moduleName_);
7970 return WSError::WS_OK;
7971 }
7972 return WSError::WS_ERROR_INVALID_SESSION;
7973 };
7974 return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
7975 }
7976
UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)7977 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
7978 {
7979 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7980 auto task = [this, persistentId, haveListener, callingPid]() {
7981 TLOGI(WmsLogTag::WMS_IMMS,
7982 "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
7983 persistentId, haveListener);
7984 auto sceneSession = GetSceneSession(persistentId);
7985 if (sceneSession == nullptr) {
7986 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
7987 return WSError::WS_DO_NOTHING;
7988 }
7989 if (callingPid != sceneSession->GetCallingPid()) {
7990 TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
7991 return WSError::WS_ERROR_INVALID_PERMISSION;
7992 }
7993 if (haveListener) {
7994 avoidAreaListenerSessionSet_.insert(persistentId);
7995 UpdateAvoidArea(persistentId);
7996 } else {
7997 lastUpdatedAvoidArea_.erase(persistentId);
7998 avoidAreaListenerSessionSet_.erase(persistentId);
7999 }
8000 return WSError::WS_OK;
8001 };
8002 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
8003 }
8004
UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId, const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)8005 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
8006 const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
8007 {
8008 if (sceneSession == nullptr) {
8009 TLOGI(WmsLogTag::WMS_IMMS, "scene session null no need update avoid area");
8010 return false;
8011 }
8012 if (lastUpdatedAvoidArea_.find(persistentId) == lastUpdatedAvoidArea_.end()) {
8013 lastUpdatedAvoidArea_[persistentId] = {};
8014 }
8015
8016 bool needUpdate = true;
8017 if (auto iter = lastUpdatedAvoidArea_[persistentId].find(avoidAreaType);
8018 iter != lastUpdatedAvoidArea_[persistentId].end()) {
8019 needUpdate = iter->second != avoidArea;
8020 } else {
8021 if (avoidArea.isEmptyAvoidArea()) {
8022 TLOGI(WmsLogTag::WMS_IMMS, "window %{public}d type %{public}d empty avoid area",
8023 persistentId, avoidAreaType);
8024 needUpdate = false;
8025 return needUpdate;
8026 }
8027 }
8028 if (needUpdate) {
8029 lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
8030 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
8031 }
8032
8033 return needUpdate;
8034 }
8035
UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)8036 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
8037 {
8038 bool ret = true;
8039 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
8040 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
8041 for (auto& persistentId : avoidAreaListenerSessionSet_) {
8042 auto sceneSession = GetSceneSession(persistentId);
8043 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8044 continue;
8045 }
8046 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8047 ret = UpdateSessionAvoidAreaIfNeed(
8048 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8049 needUpdate = needUpdate || ret;
8050 }
8051
8052 return;
8053 }
8054
CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)8055 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
8056 {
8057 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
8058 !avoidArea.rightRect_.IsUninitializedRect()) {
8059 return false;
8060 }
8061 if (avoidArea.bottomRect_.IsUninitializedRect()) {
8062 return true;
8063 }
8064 auto diff =
8065 std::abs(avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) - sessionBottom);
8066 return isVisible && diff <= 1;
8067 }
8068
UpdateNormalSessionAvoidArea( const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)8069 void SceneSessionManager::UpdateNormalSessionAvoidArea(
8070 const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
8071 {
8072 bool ret = true;
8073 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8074 TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
8075 persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
8076 needUpdate = false;
8077 return;
8078 }
8079 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8080 TLOGD(WmsLogTag::WMS_IMMS,
8081 "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
8082 needUpdate = false;
8083 return;
8084 }
8085 uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
8086 uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8087 for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
8088 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8089 if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
8090 !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8091 sceneSession->GetSessionRect().height_)) {
8092 continue;
8093 }
8094 ret = UpdateSessionAvoidAreaIfNeed(
8095 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8096 needUpdate = needUpdate || ret;
8097 }
8098
8099 return;
8100 }
8101
NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)8102 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
8103 {
8104 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
8105 auto sceneSession = GetSceneSession(windowId);
8106 if (sceneSession == nullptr) {
8107 WLOGFW("window not exist: %{public}d", windowId);
8108 return;
8109 }
8110
8111 wptr<SceneSession> weakSceneSession(sceneSession);
8112 WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
8113 auto task = [weakSceneSession, startMoving]() -> WSError {
8114 auto scnSession = weakSceneSession.promote();
8115 if (scnSession == nullptr) {
8116 WLOGFW("session is null");
8117 return WSError::WS_ERROR_NULLPTR;
8118 }
8119 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8120 return WSError::WS_OK;
8121 };
8122 return taskScheduler_->PostAsyncTask(task);
8123 }
8124
UpdateAvoidArea(int32_t persistentId)8125 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8126 {
8127 auto task = [this, persistentId] {
8128 bool needUpdate = false;
8129 auto sceneSession = GetSceneSession(persistentId);
8130 if (sceneSession == nullptr) {
8131 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8132 return;
8133 }
8134 WindowType type = sceneSession->GetWindowType();
8135 if (sceneSession->IsImmersiveType()) {
8136 UpdateAvoidSessionAvoidArea(type, needUpdate);
8137 } else {
8138 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8139 }
8140 if (needUpdate) {
8141 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8142 }
8143 return;
8144 };
8145 taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8146 return;
8147 }
8148
UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)8149 void SceneSessionManager::UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)
8150 {
8151 auto task = [this, persistentId, type] {
8152 auto sceneSession = GetSceneSession(persistentId);
8153 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8154 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is nullptr or invisible", persistentId);
8155 return;
8156 }
8157 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8158 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d has no listener, no need update", persistentId);
8159 return;
8160 }
8161 if (sceneSession->IsImmersiveType()) {
8162 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is immersive type", persistentId);
8163 return;
8164 }
8165 auto avoidArea = sceneSession->GetAvoidAreaByType(type);
8166 if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && !CheckAvoidAreaForAINavigationBar(
8167 isAINavigationBarVisible_, avoidArea, sceneSession->GetSessionRect().height_)) {
8168 return;
8169 }
8170 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, type);
8171 };
8172 taskScheduler_->PostAsyncTask(task, "UpdateAvoidAreaByType:PID:" + std::to_string(persistentId));
8173 }
8174
UpdateGestureBackEnabled(int32_t persistentId)8175 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8176 {
8177 auto task = [this, persistentId] {
8178 auto sceneSession = GetSceneSession(persistentId);
8179 if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8180 TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8181 return;
8182 }
8183 auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8184 if (needEnableGestureBack) {
8185 gestureBackEnableWindowIdSet_.erase(persistentId);
8186 } else {
8187 gestureBackEnableWindowIdSet_.insert(persistentId);
8188 }
8189 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8190 sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8191 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8192 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8193 enterRecent_.load() || !sceneSession->IsFocused()) {
8194 needEnableGestureBack = true;
8195 }
8196 if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8197 gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8198 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8199 } else {
8200 TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8201 }
8202 };
8203 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8204 }
8205
UpdateOccupiedAreaIfNeed(const int32_t& persistentId)8206 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8207 {
8208 auto task = [this, persistentId]() {
8209 sptr<SceneSession> keyboardSession = nullptr;
8210 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8211 for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8212 auto sceneSession = item->second;
8213 if (sceneSession != nullptr &&
8214 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8215 keyboardSession = sceneSession;
8216 break;
8217 }
8218 }
8219 if (keyboardSession == nullptr) {
8220 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8221 return;
8222 }
8223 if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8224 return;
8225 }
8226
8227 keyboardSession->OnCallingSessionUpdated();
8228 return;
8229 };
8230 taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8231 return;
8232 }
8233
NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)8234 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8235 {
8236 TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8237 isVisible, persistentId);
8238 auto task = [this, persistentId, isVisible] {
8239 auto sceneSession = GetSceneSession(persistentId);
8240 if (sceneSession == nullptr) {
8241 TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8242 return;
8243 }
8244 sceneSession->SetIsStatusBarVisible(isVisible);
8245 };
8246 taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8247 return WSError::WS_OK;
8248 }
8249
NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)8250 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8251 {
8252 WLOGFI("isVisible: %{public}u, "
8253 "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8254 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8255 auto task = [this, isVisible, barArea, displayId]() {
8256 bool isNeedNotify = isAINavigationBarVisible_ != isVisible;
8257 {
8258 std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8259 bool isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8260 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8261 currAINavigationBarAreaMap_[displayId] != barArea;
8262 if (isNeedUpdate) {
8263 isAINavigationBarVisible_ = isVisible;
8264 currAINavigationBarAreaMap_.clear();
8265 currAINavigationBarAreaMap_[displayId] = barArea;
8266 }
8267 if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8268 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8269 currAINavigationBarAreaMap_[displayId] = WSRect();
8270 }
8271 }
8272 if (isNeedNotify) {
8273 WLOGFI("NotifyAINavigationBar: enter: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8274 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8275 for (auto persistentId : avoidAreaListenerSessionSet_) {
8276 NotifySessionAINavigationBarChange(persistentId);
8277 }
8278 }
8279 };
8280 taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
8281 return WSError::WS_OK;
8282 }
8283
NotifySessionAINavigationBarChange(int32_t persistentId)8284 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
8285 {
8286 auto sceneSession = GetSceneSession(persistentId);
8287 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8288 return;
8289 }
8290 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8291 if (!CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8292 sceneSession->GetSessionRect().height_)) {
8293 return;
8294 }
8295 WLOGFI("NotifyAINavigationBarShowStatus: persistentId: %{public}d, "
8296 "{%{public}d,%{public}d,%{public}d,%{public}d}", persistentId,
8297 avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
8298 avoidArea.bottomRect_.width_, avoidArea.bottomRect_.height_);
8299 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
8300 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8301 }
8302
GetAINavigationBarArea(uint64_t displayId)8303 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
8304 {
8305 std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8306 if (currAINavigationBarAreaMap_.count(displayId) == 0) {
8307 return {};
8308 }
8309 return currAINavigationBarAreaMap_[displayId];
8310 }
8311
UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)8312 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
8313 {
8314 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8315 auto task = [this, persistentId, haveListener, callingPid]() {
8316 TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
8317 persistentId, haveListener);
8318 auto sceneSession = GetSceneSession(persistentId);
8319 if (sceneSession == nullptr) {
8320 TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
8321 return WSError::WS_DO_NOTHING;
8322 }
8323 if (callingPid != sceneSession->GetCallingPid()) {
8324 TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
8325 return WSError::WS_ERROR_INVALID_PERMISSION;
8326 }
8327 if (haveListener) {
8328 touchOutsideListenerSessionSet_.insert(persistentId);
8329 } else {
8330 touchOutsideListenerSessionSet_.erase(persistentId);
8331 }
8332 return WSError::WS_OK;
8333 };
8334 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
8335 }
8336
UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)8337 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
8338 {
8339 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
8340 auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
8341 WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
8342 persistentId, haveListener);
8343 auto sceneSession = GetSceneSession(persistentId);
8344 if (sceneSession == nullptr) {
8345 WLOGFD("sceneSession is nullptr.");
8346 return WSError::WS_DO_NOTHING;
8347 }
8348 if (callingPid != sceneSession->GetCallingPid()) {
8349 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
8350 return WSError::WS_ERROR_INVALID_PERMISSION;
8351 }
8352 if (haveListener) {
8353 windowVisibilityListenerSessionSet_.insert(persistentId);
8354 sceneSession->NotifyWindowVisibility();
8355 } else {
8356 windowVisibilityListenerSessionSet_.erase(persistentId);
8357 }
8358 return WSError::WS_OK;
8359 };
8360 return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
8361 }
8362
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)8363 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
8364 {
8365 processVirtualPixelRatioChangeFunc_ = func;
8366 WLOGFI("SetVirtualPixelRatioChangeListener");
8367 }
8368
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)8369 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8370 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8371 {
8372 if (displayInfo == nullptr) {
8373 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
8374 return;
8375 }
8376 auto task = [this, displayInfo]() {
8377 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8378 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
8379 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
8380 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
8381 displayInfo->GetWidth(), displayInfo->GetHeight()
8382 };
8383 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
8384 }
8385 for (const auto &item : sceneSessionMap_) {
8386 auto scnSession = item.second;
8387 if (scnSession == nullptr) {
8388 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
8389 continue;
8390 }
8391 if (scnSession->GetSessionProperty() != nullptr &&
8392 scnSession->GetSessionProperty()->GetDisplayId() != displayInfo->GetDisplayId()) {
8393 continue;
8394 }
8395 SessionInfo sessionInfo = scnSession->GetSessionInfo();
8396 if (sessionInfo.isSystem_) {
8397 continue;
8398 }
8399 if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8400 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
8401 scnSession->UpdateDensity();
8402 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
8403 "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
8404 scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8405 }
8406 }
8407 UpdateDisplayRegion(displayInfo);
8408 return WSError::WS_OK;
8409 };
8410 taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
8411 }
8412
ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)8413 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8414 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8415 {
8416 if (displayInfo == nullptr) {
8417 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
8418 return;
8419 }
8420 auto task = [this, displayInfo]() {
8421 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8422 for (const auto &item : sceneSessionMap_) {
8423 auto scnSession = item.second;
8424 if (scnSession == nullptr) {
8425 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
8426 continue;
8427 }
8428 if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8429 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
8430 continue;
8431 }
8432 if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
8433 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
8434 scnSession->GetRotation() != displayInfo->GetRotation()) {
8435 scnSession->UpdateRotationAvoidArea();
8436 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
8437 "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
8438 item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8439 }
8440 scnSession->SetRotation(displayInfo->GetRotation());
8441 scnSession->UpdateOrientation();
8442 }
8443 UpdateDisplayRegion(displayInfo);
8444 return WSError::WS_OK;
8445 };
8446 taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
8447 }
8448
ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)8449 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
8450 {
8451 if (displayInfo == nullptr) {
8452 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
8453 return;
8454 }
8455
8456 auto task = [displayInfo]() -> WSError {
8457 ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
8458 displayInfo->GetScaleX(),
8459 displayInfo->GetScaleY(),
8460 displayInfo->GetPivotX(),
8461 displayInfo->GetPivotY(),
8462 displayInfo->GetTranslateX(),
8463 displayInfo->GetTranslateY());
8464 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
8465 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
8466 return WSError::WS_OK;
8467 };
8468 return taskScheduler_->PostAsyncTask(task);
8469 }
8470
OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo, const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)8471 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8472 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8473 {
8474 WLOGFD("type: %{public}u", type);
8475 switch (type) {
8476 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
8477 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
8478 displayInfo, displayInfoMap, type);
8479 break;
8480 }
8481 case DisplayStateChangeType::UPDATE_ROTATION: {
8482 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
8483 displayInfo, displayInfoMap, type);
8484 break;
8485 }
8486 case DisplayStateChangeType::UPDATE_SCALE: {
8487 SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
8488 break;
8489 }
8490 default:
8491 return;
8492 }
8493 }
8494
OnScreenshot(DisplayId displayId)8495 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
8496 {
8497 SceneSessionManager::GetInstance().OnScreenshot(displayId);
8498 }
8499
OnScreenshot(DisplayId displayId)8500 void SceneSessionManager::OnScreenshot(DisplayId displayId)
8501 {
8502 auto task = [this, displayId]() {
8503 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8504 for (const auto& iter : sceneSessionMap_) {
8505 auto sceneSession = iter.second;
8506 if (sceneSession == nullptr) {
8507 continue;
8508 }
8509 auto state = sceneSession->GetSessionState();
8510 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
8511 sceneSession->NotifyScreenshot();
8512 }
8513 }
8514 };
8515 taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
8516 }
8517
ClearSession(int32_t persistentId)8518 WSError SceneSessionManager::ClearSession(int32_t persistentId)
8519 {
8520 WLOGFI("id: %{public}d", persistentId);
8521 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8522 WLOGFE("The caller is not system-app, can not use system-api");
8523 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8524 }
8525 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8526 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8527 return WSError::WS_ERROR_INVALID_PERMISSION;
8528 }
8529 auto task = [this, persistentId]() {
8530 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8531 return ClearSession(sceneSession);
8532 };
8533 taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
8534 return WSError::WS_OK;
8535 }
8536
ClearSession(sptr<SceneSession> sceneSession)8537 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
8538 {
8539 WLOGFD("Enter");
8540 if (sceneSession == nullptr) {
8541 WLOGFE("session is nullptr");
8542 return WSError::WS_ERROR_INVALID_SESSION;
8543 }
8544 if (!IsSessionClearable(sceneSession)) {
8545 WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
8546 return WSError::WS_ERROR_INVALID_SESSION;
8547 }
8548 const WSError errCode = sceneSession->Clear();
8549 return errCode;
8550 }
8551
ClearAllSessions()8552 WSError SceneSessionManager::ClearAllSessions()
8553 {
8554 WLOGFI("Enter");
8555 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8556 WLOGFE("The caller is not system-app, can not use system-api");
8557 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8558 }
8559 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8560 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8561 return WSError::WS_ERROR_INVALID_PERMISSION;
8562 }
8563 auto task = [this]() {
8564 std::vector<sptr<SceneSession>> sessionVector;
8565 GetAllClearableSessions(sessionVector);
8566 for (uint32_t i = 0; i < sessionVector.size(); i++) {
8567 ClearSession(sessionVector[i]);
8568 }
8569 return WSError::WS_OK;
8570 };
8571 taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
8572 return WSError::WS_OK;
8573 }
8574
GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)8575 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
8576 {
8577 WLOGFI("Enter");
8578 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8579 for (const auto &item : sceneSessionMap_) {
8580 auto scnSession = item.second;
8581 if (IsSessionClearable(scnSession)) {
8582 sessionVector.push_back(scnSession);
8583 }
8584 }
8585 }
8586
LockSession(int32_t sessionId)8587 WSError SceneSessionManager::LockSession(int32_t sessionId)
8588 {
8589 WLOGFI("id: %{public}d", sessionId);
8590 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8591 WLOGFE("The caller is not system-app, can not use system-api");
8592 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8593 }
8594 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8595 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8596 return WSError::WS_ERROR_INVALID_PERMISSION;
8597 }
8598 auto task = [this, sessionId]() {
8599 auto sceneSession = GetSceneSession(sessionId);
8600 if (sceneSession == nullptr) {
8601 WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
8602 return WSError::WS_ERROR_INVALID_PARAM;
8603 }
8604 sceneSession->SetSessionInfoLockedState(true);
8605 return WSError::WS_OK;
8606 };
8607 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
8608 }
8609
UnlockSession(int32_t sessionId)8610 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
8611 {
8612 WLOGFI("id: %{public}d", sessionId);
8613 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8614 WLOGFE("The caller is not system-app, can not use system-api");
8615 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8616 }
8617 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8618 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8619 return WSError::WS_ERROR_INVALID_PERMISSION;
8620 }
8621 auto task = [this, sessionId]() {
8622 auto sceneSession = GetSceneSession(sessionId);
8623 if (sceneSession == nullptr) {
8624 WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
8625 return WSError::WS_ERROR_INVALID_PARAM;
8626 }
8627 sceneSession->SetSessionInfoLockedState(false);
8628 return WSError::WS_OK;
8629 };
8630 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
8631 }
8632
MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)8633 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
8634 {
8635 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8636 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8637 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8638 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8639 }
8640 if (!SessionPermission::VerifySessionPermission()) {
8641 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8642 return WSError::WS_ERROR_INVALID_PERMISSION;
8643 }
8644
8645 return WSError::WS_OK;
8646 }
8647
MoveSessionsToBackground(const std::vector<int32_t>& sessionIds, std::vector<int32_t>& result)8648 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
8649 std::vector<int32_t>& result)
8650 {
8651 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
8652 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8653 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8654 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8655 }
8656 if (!SessionPermission::VerifySessionPermission()) {
8657 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8658 return WSError::WS_ERROR_INVALID_PERMISSION;
8659 }
8660
8661 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
8662 return WSError::WS_OK;
8663 }
8664
IsSessionClearable(sptr<SceneSession> scnSession)8665 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
8666 {
8667 if (scnSession == nullptr) {
8668 WLOGFI("scnSession is nullptr");
8669 return false;
8670 }
8671 SessionInfo sessionInfo = scnSession->GetSessionInfo();
8672 if (sessionInfo.abilityInfo == nullptr) {
8673 WLOGFI("scnSession abilityInfo is nullptr");
8674 return false;
8675 }
8676 if (sessionInfo.abilityInfo->excludeFromMissions) {
8677 WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
8678 return false;
8679 }
8680 if (sessionInfo.abilityInfo->unclearableMission) {
8681 WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
8682 return false;
8683 }
8684 if (sessionInfo.isSystem_) {
8685 WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
8686 return false;
8687 }
8688 if (sessionInfo.lockedState) {
8689 WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
8690 return false;
8691 }
8692
8693 return true;
8694 }
8695
RegisterIAbilityManagerCollaborator(int32_t type, const sptr<AAFwk::IAbilityManagerCollaborator>& impl)8696 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
8697 const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
8698 {
8699 WLOGFI("type: %{public}d", type);
8700 auto isSaCall = SessionPermission::IsSACalling();
8701 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8702 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8703 return WSError::WS_ERROR_INVALID_PERMISSION;
8704 }
8705 if (!CheckCollaboratorType(type)) {
8706 WLOGFW("collaborator register failed, invalid type.");
8707 return WSError::WS_ERROR_INVALID_TYPE;
8708 }
8709 if (impl == nullptr) {
8710 TLOGE(WmsLogTag::DEFAULT, "Collaborator is nullptr");
8711 return WSError::WS_ERROR_NULLPTR;
8712 }
8713 if (impl->AsObject() == nullptr || !impl->AsObject()->AddDeathRecipient(collaboratorDeathRecipient_)) {
8714 TLOGE(WmsLogTag::DEFAULT, "Failed to add collaborator death recipient");
8715 return WSError::WS_ERROR_IPC_FAILED;
8716 }
8717 {
8718 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8719 collaboratorMap_[type] = impl;
8720 }
8721 auto task = [this] {
8722 if (abilityManagerCollaboratorRegisteredFunc_) {
8723 abilityManagerCollaboratorRegisteredFunc_();
8724 }
8725 };
8726 taskScheduler_->PostTask(task, __func__);
8727 return WSError::WS_OK;
8728 }
8729
UnregisterIAbilityManagerCollaborator(int32_t type)8730 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
8731 {
8732 WLOGFI("type: %{public}d", type);
8733 auto isSaCall = SessionPermission::IsSACalling();
8734 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8735 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
8736 return WSError::WS_ERROR_INVALID_PERMISSION;
8737 }
8738 if (!CheckCollaboratorType(type)) {
8739 WLOGFE("collaborator unregister failed, invalid type.");
8740 return WSError::WS_ERROR_INVALID_TYPE;
8741 }
8742 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(type);
8743 if (collaborator != nullptr && collaborator->AsObject() != nullptr) {
8744 TLOGI(WmsLogTag::DEFAULT, "Remove collaborator death recipient");
8745 collaborator->AsObject()->RemoveDeathRecipient(collaboratorDeathRecipient_);
8746 }
8747 {
8748 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
8749 collaboratorMap_.erase(type);
8750 }
8751 return WSError::WS_OK;
8752 }
8753
ClearAllCollaboratorSessions()8754 void SceneSessionManager::ClearAllCollaboratorSessions()
8755 {
8756 TLOGI(WmsLogTag::DEFAULT, "run");
8757 std::vector<sptr<SceneSession>> collaboratorSessions;
8758 {
8759 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8760 for (const auto& [_, sceneSession] : sceneSessionMap_) {
8761 if (sceneSession != nullptr && CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
8762 collaboratorSessions.push_back(sceneSession);
8763 }
8764 }
8765 }
8766 for (const auto& sceneSession : collaboratorSessions) {
8767 sceneSession->Clear();
8768 }
8769 }
8770
CheckCollaboratorType(int32_t type)8771 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
8772 {
8773 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
8774 WLOGFD("type is invalid");
8775 return false;
8776 }
8777 return true;
8778 }
8779
CheckIfReuseSession(SessionInfo& sessionInfo)8780 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
8781 {
8782 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
8783 sessionInfo.moduleName_);
8784 if (abilityInfo == nullptr) {
8785 WLOGFE("abilityInfo is nullptr!");
8786 return BrokerStates::BROKER_UNKOWN;
8787 }
8788 sessionInfo.abilityInfo = abilityInfo;
8789 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
8790 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
8791 collaboratorType = CollaboratorType::RESERVE_TYPE;
8792 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
8793 collaboratorType = CollaboratorType::OTHERS_TYPE;
8794 }
8795 if (!CheckCollaboratorType(collaboratorType)) {
8796 WLOGFW("checked not collaborator!");
8797 return BrokerStates::BROKER_UNKOWN;
8798 }
8799 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
8800 sessionInfo.collaboratorType_ = collaboratorType;
8801 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8802 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
8803 WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
8804 sessionInfo.reuse = true;
8805 } else {
8806 sessionInfo.reuse = false;
8807 }
8808 WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
8809 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
8810 return resultValue;
8811 }
8812
NotifyStartAbility( int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)8813 BrokerStates SceneSessionManager::NotifyStartAbility(
8814 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
8815 {
8816 WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
8817 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8818 if (collaborator == nullptr) {
8819 return BrokerStates::BROKER_UNKOWN;
8820 }
8821 if (sessionInfo.want == nullptr) {
8822 WLOGFI("sessionInfo.want is nullptr, init");
8823 sessionInfo.want = std::make_shared<AAFwk::Want>();
8824 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
8825 sessionInfo.moduleName_);
8826 }
8827 auto accessTokenIDEx = sessionInfo.callingTokenId_;
8828 if (collaborator != nullptr) {
8829 containerStartAbilityTime = std::chrono::duration_cast<std::chrono::milliseconds>(
8830 std::chrono::system_clock::now().time_since_epoch()).count();
8831
8832 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8833 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
8834 WLOGFI("want affinity exit %{public}s.", affinity.c_str());
8835 return BrokerStates::BROKER_UNKOWN;
8836 }
8837 sessionInfo.want->SetParam("oh_persistentId", persistentId);
8838 int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
8839 currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
8840 WLOGFI("collaborator ret: %{public}d", ret);
8841 if (ret == 0) {
8842 return BrokerStates::BROKER_STARTED;
8843 } else {
8844 return BrokerStates::BROKER_NOT_START;
8845 }
8846 }
8847 return BrokerStates::BROKER_UNKOWN;
8848 }
8849
NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)8850 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
8851 {
8852 if (sceneSession == nullptr) {
8853 WLOGFE("sceneSession is nullptr");
8854 return;
8855 }
8856 if (sessionInfo.want == nullptr) {
8857 WLOGFI("sessionInfo.want is nullptr");
8858 return;
8859 }
8860 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8861 if (collaborator == nullptr) {
8862 return;
8863 }
8864 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8865 if (abilitySessionInfo == nullptr) {
8866 WLOGFE("abilitySessionInfo is nullptr");
8867 return;
8868 }
8869 abilitySessionInfo->want = *(sessionInfo.want);
8870 if (collaborator != nullptr) {
8871 int32_t missionId = abilitySessionInfo->persistentId;
8872 std::string bundleName = sessionInfo.bundleName_;
8873 int64_t timestamp = containerStartAbilityTime;
8874 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
8875 WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
8876 missionId, bundleName.c_str());
8877 collaborator->NotifyMissionCreated(abilitySessionInfo);
8878 }
8879 }
8880
NotifyLoadAbility(int32_t collaboratorType, sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)8881 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
8882 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
8883 {
8884 WLOGFD("type: %{public}d", collaboratorType);
8885 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8886 if (collaborator != nullptr) {
8887 WLOGFI("called NotifyLoadAbility");
8888 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
8889 }
8890 }
8891
8892
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)8893 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
8894 {
8895 WLOGFD("Enter");
8896 if (sceneSession == nullptr) {
8897 WLOGFE("sceneSession is nullptr");
8898 return;
8899 }
8900 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
8901 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
8902 if (collaborator != nullptr) {
8903 WLOGFI("called UpdateMissionInfo");
8904 collaborator->UpdateMissionInfo(abilitySessionInfo);
8905 }
8906 }
8907
NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)8908 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
8909 {
8910 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8911 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8912 if (collaborator != nullptr) {
8913 WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
8914 collaborator->NotifyMoveMissionToForeground(persistentId);
8915 }
8916 }
8917
NotifyClearSession(int32_t collaboratorType, int32_t persistentId)8918 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
8919 {
8920 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
8921 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
8922 if (collaborator != nullptr) {
8923 WLOGFI("called NotifyClearMission %{public}d", persistentId);
8924 collaborator->NotifyClearMission(persistentId);
8925 }
8926 }
8927
PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)8928 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
8929 {
8930 if (sceneSession == nullptr) {
8931 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
8932 return false;
8933 }
8934 std::string sessionAffinity;
8935 TLOGI(WmsLogTag::WMS_LIFE, "call");
8936 if (sceneSession->GetSessionInfo().want != nullptr) {
8937 sessionAffinity = sceneSession->GetSessionInfo().want
8938 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
8939 }
8940 if (sessionAffinity.empty()) {
8941 TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
8942 BrokerStates notifyReturn = NotifyStartAbility(
8943 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
8944 if (notifyReturn != BrokerStates::BROKER_STARTED) {
8945 TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
8946 return false;
8947 }
8948 }
8949 if (sceneSession->GetSessionInfo().want != nullptr) {
8950 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
8951 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
8952 TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
8953 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
8954 sceneSession->GetSessionInfo().sessionAffinity.c_str());
8955 } else {
8956 TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
8957 }
8958 return true;
8959 }
8960
PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)8961 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
8962 {
8963 if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
8964 return false;
8965 }
8966 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
8967 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
8968 return true;
8969 }
8970
AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)8971 void SceneSessionManager::AddWindowDragHotArea(DisplayId displayId, uint32_t type, WSRect& area)
8972 {
8973 TLOGI(WmsLogTag::WMS_LAYOUT, "displayId: %{public}" PRIu64 ", "
8974 "type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
8975 "height: %{public}d", displayId, type, area.posX_, area.posY_, area.width_, area.height_);
8976 SceneSession::AddOrUpdateWindowDragHotArea(displayId, type, area);
8977 }
8978
UpdateMaximizeMode(int32_t persistentId, bool isMaximize)8979 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
8980 {
8981 auto task = [this, persistentId, isMaximize]() -> WSError {
8982 WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
8983 auto sceneSession = GetSceneSession(persistentId);
8984 if (sceneSession == nullptr) {
8985 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
8986 return WSError::WS_ERROR_INVALID_WINDOW;
8987 }
8988 sceneSession->UpdateMaximizeMode(isMaximize);
8989 return WSError::WS_OK;
8990 };
8991 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
8992 return WSError::WS_OK;
8993 }
8994
GetIsLayoutFullScreen(bool& isLayoutFullScreen)8995 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
8996 {
8997 auto task = [this, &isLayoutFullScreen]() {
8998 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8999 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9000 auto sceneSession = item->second;
9001 if (sceneSession == nullptr) {
9002 WLOGFE("Session is nullptr");
9003 continue;
9004 }
9005 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9006 continue;
9007 }
9008 auto state = sceneSession->GetSessionState();
9009 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9010 continue;
9011 }
9012 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9013 continue;
9014 }
9015 auto property = sceneSession->GetSessionProperty();
9016 if (property == nullptr) {
9017 WLOGFE("Property is nullptr");
9018 continue;
9019 }
9020 isLayoutFullScreen = property->IsLayoutFullScreen();
9021 auto persistentId = sceneSession->GetPersistentId();
9022 if (isLayoutFullScreen) {
9023 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
9024 return WSError::WS_OK;
9025 } else {
9026 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
9027 }
9028 }
9029 WLOGFD("No immersive window");
9030 return WSError::WS_OK;
9031 };
9032
9033 taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
9034 return WSError::WS_OK;
9035 }
9036
UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)9037 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
9038 {
9039 auto scnSession = GetSceneSession(persistentId);
9040 if (!scnSession) {
9041 WLOGFE("session is nullptr");
9042 return WSError::WS_ERROR_INVALID_WINDOW;
9043 }
9044 auto fromScreenId = scnSession->GetSessionInfo().screenId_;
9045 scnSession->SetScreenId(screenId);
9046 auto sessionProperty = scnSession->GetSessionProperty();
9047 if (!sessionProperty) {
9048 WLOGFE("Property is null, synchronous screenId failed");
9049 return WSError::WS_ERROR_NULLPTR;
9050 }
9051 sessionProperty->SetDisplayId(screenId);
9052 WLOGFD("Session move display %{public}" PRIu64 " from %{public}" PRIu64, screenId, fromScreenId);
9053 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
9054 scnSession->NotifyDisplayMove(fromScreenId, screenId);
9055 scnSession->UpdateDensity();
9056 return WSError::WS_OK;
9057 }
9058
NotifyStackEmpty(int32_t persistentId)9059 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
9060 {
9061 TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
9062 auto task = [this, persistentId]() {
9063 auto scnSession = GetSceneSession(persistentId);
9064 if (!scnSession) {
9065 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
9066 return WSError::WS_ERROR_INVALID_WINDOW;
9067 }
9068 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
9069 return WSError::WS_OK;
9070 };
9071 taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
9072 return WSError::WS_OK;
9073 }
9074
OnImmersiveStateChange(ScreenId screenId, bool& immersive)9075 void DisplayChangeListener::OnImmersiveStateChange(ScreenId screenId, bool& immersive)
9076 {
9077 immersive = SceneSessionManager::GetInstance().GetImmersiveState(screenId);
9078 }
9079
GetImmersiveState(ScreenId screenId)9080 bool SceneSessionManager::GetImmersiveState(ScreenId screenId)
9081 {
9082 auto task = [this, screenId] {
9083 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9084 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9085 auto sceneSession = item->second;
9086 if (sceneSession == nullptr) {
9087 WLOGFE("Session is nullptr");
9088 continue;
9089 }
9090 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9091 continue;
9092 }
9093 auto state = sceneSession->GetSessionState();
9094 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9095 continue;
9096 }
9097 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9098 continue;
9099 }
9100 auto property = sceneSession->GetSessionProperty();
9101 if (property == nullptr) {
9102 WLOGFE("Property is nullptr");
9103 continue;
9104 }
9105 if (property->GetDisplayId() != screenId) {
9106 continue;
9107 }
9108 auto sysBarProperty = property->GetSystemBarProperty();
9109 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
9110 WLOGI("GetImmersiveState, window is immersive. id:%{public}d", sceneSession->GetPersistentId());
9111 return true;
9112 } else {
9113 WLOGI("GetImmersiveState, statusBar is enabled. id:%{public}d", sceneSession->GetPersistentId());
9114 break;
9115 }
9116 }
9117 WLOGI("GetImmersiveState, not immersive");
9118 return false;
9119 };
9120 return taskScheduler_->PostSyncTask(task, "GetImmersiveState");
9121 }
9122
NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason, bool withAnimation)9123 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
9124 bool withAnimation)
9125 {
9126 session->NotifySessionForeground(reason, withAnimation);
9127 }
9128
NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason, bool withAnimation, bool isFromInnerkits)9129 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
9130 bool withAnimation, bool isFromInnerkits)
9131 {
9132 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
9133 }
9134
UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)9135 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
9136 {
9137 auto sceneSession = GetSceneSession(persistentId);
9138 if (sceneSession == nullptr) {
9139 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9140 return WSError::WS_ERROR_INVALID_WINDOW;
9141 }
9142 return sceneSession->UpdateTitleInTargetPos(isShow, height);
9143 }
9144
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)9145 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9146 {
9147 WLOGFI("AppAnrListener OnAppDebugStarted");
9148 if (debugInfos.empty()) {
9149 WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9150 return;
9151 }
9152 }
9153
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)9154 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9155 {
9156 WLOGFI("AppAnrListener OnAppDebugStoped");
9157 if (debugInfos.empty()) {
9158 WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9159 return;
9160 }
9161 }
9162
FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)9163 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9164 {
9165 if (!Session::IsScbCoreEnabled()) {
9166 return;
9167 }
9168 auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9169 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9170 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9171 {
9172 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9173 nextFlushCompletedCV_.notify_all();
9174 }
9175 processingFlushUIParams_.store(true);
9176 {
9177 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9178 for (const auto& item : sceneSessionMap_) {
9179 auto sceneSession = item.second;
9180 if (sceneSession == nullptr) {
9181 continue;
9182 }
9183 if (sceneSession->GetSessionInfo().screenId_ != screenId) {
9184 continue;
9185 }
9186 auto iter = uiParams.find(sceneSession->GetPersistentId());
9187 if (iter != uiParams.end()) {
9188 sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9189 } else {
9190 sessionMapDirty_ |= sceneSession->UpdateUIParam();
9191 }
9192 }
9193 }
9194 processingFlushUIParams_.store(false);
9195
9196 // post process if dirty
9197 if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9198 static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9199 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9200 for (const auto& item : uiParams) {
9201 TLOGD(WmsLogTag::WMS_PIPELINE,
9202 "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX: %{public}f, transY: %{public}f,"
9203 " needSync: %{public}d, interactive: %{public}d",
9204 item.first, item.second.zOrder_, item.second.rect_.ToString().c_str(), item.second.transX_,
9205 item.second.transY_, item.second.needSync_, item.second.interactive_);
9206 }
9207 ProcessFocusZOrderChange(sessionMapDirty_);
9208 PostProcessFocus();
9209 PostProcessProperty(sessionMapDirty_);
9210 NotifyAllAccessibilityInfo();
9211 AnomalyDetection::SceneZOrderCheckProcess();
9212 } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9213 PostProcessProperty(sessionMapDirty_);
9214 }
9215 FlushWindowInfoToMMI();
9216 sessionMapDirty_ = 0;
9217 {
9218 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9219 for (const auto& item : sceneSessionMap_) {
9220 auto sceneSession = item.second;
9221 if (sceneSession == nullptr) {
9222 continue;
9223 }
9224 sceneSession->ResetDirtyFlags();
9225 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9226 sceneSession->SetUIStateDirty(false);
9227 }
9228 }
9229 }
9230 };
9231 taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9232 }
9233
ProcessFocusZOrderChange(uint32_t dirty)9234 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty) {
9235 if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9236 return;
9237 }
9238 if (!systemConfig_.IsPhoneWindow() && !systemConfig_.IsPadWindow()) {
9239 return;
9240 }
9241 TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9242 auto focusedSession = GetSceneSession(focusedSessionId_);
9243 // only when it's from a high zOrder to a low zOrder
9244 if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9245 focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9246 return;
9247 }
9248 auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9249 if (voiceInteractionSession == nullptr) {
9250 return;
9251 }
9252 TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9253 "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9254 voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9255 if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9256 focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9257 return;
9258 }
9259 RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9260 }
9261
PostProcessFocus()9262 void SceneSessionManager::PostProcessFocus()
9263 {
9264 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9265 // priority process focus requests from top to bottom
9266 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9267 {
9268 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9269 for (auto& iter : sceneSessionMap_) {
9270 auto session = iter.second;
9271 if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9272 continue;
9273 }
9274 processingSessions.push_back(iter);
9275 }
9276 }
9277 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
9278 bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
9279 !rhs.second->GetPostProcessFocusState().isFocused_;
9280 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
9281 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
9282 return focusCmp || lhsZOrder > rhsZOrder;
9283 };
9284 std::sort(processingSessions.begin(), processingSessions.end(), cmp);
9285
9286 // only change focus one time
9287 bool focusChanged = false;
9288 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9289 auto session = iter->second;
9290 if (session == nullptr) {
9291 WLOGFE("session is nullptr");
9292 continue;
9293 }
9294 TLOGD(WmsLogTag::WMS_PIPELINE,
9295 "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
9296 session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
9297 session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
9298 if (!session->IsFocusableOnShow() &&
9299 (session->GetPostProcessFocusState().reason_ == FocusChangeReason::FOREGROUND ||
9300 session->GetPostProcessFocusState().reason_ == FocusChangeReason::APP_FOREGROUND)) {
9301 TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus", session->GetPersistentId());
9302 session->ResetPostProcessFocusState();
9303 session->SetFocusableOnShow(true);
9304 continue;
9305 }
9306 if (focusChanged) {
9307 session->ResetPostProcessFocusState();
9308 continue;
9309 }
9310 WSError ret = WSError::WS_DO_NOTHING;
9311 if (session->GetPostProcessFocusState().isFocused_) {
9312 if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
9313 ret = RequestSessionFocusImmediately(session->GetPersistentId());
9314 } else if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::RECENT) {
9315 ret = RequestSessionFocus(session->GetPersistentId(),
9316 session->GetPostProcessFocusState().byForeground_,
9317 session->GetPostProcessFocusState().reason_);
9318 } else {
9319 ret = RequestSessionFocus(session->GetPersistentId(), true,
9320 session->GetPostProcessFocusState().reason_);
9321 }
9322 } else {
9323 ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
9324 }
9325 session->ResetPostProcessFocusState();
9326 // if succeed then end process
9327 if (ret == WSError::WS_OK) {
9328 focusChanged = true;
9329 }
9330 }
9331 }
9332
PostProcessProperty(uint32_t dirty)9333 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
9334 {
9335 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
9336 if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9337 // only trigger update avoid area
9338 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9339 for (auto& iter : sceneSessionMap_) {
9340 auto session = iter.second;
9341 if (session == nullptr) {
9342 continue;
9343 }
9344 session->PostProcessNotifyAvoidArea();
9345 }
9346 return;
9347 }
9348
9349 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9350 {
9351 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9352 for (auto& iter : sceneSessionMap_) {
9353 auto session = iter.second;
9354 if (session == nullptr || !session->GetPostProcessProperty()) {
9355 continue;
9356 }
9357 processingSessions.push_back(iter);
9358 }
9359 }
9360
9361 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9362 auto session = iter->second;
9363 if (session == nullptr) {
9364 WLOGFE("session is nullptr");
9365 continue;
9366 }
9367 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
9368 UpdateForceHideState(session, session->GetSessionProperty(), true);
9369 HandleKeepScreenOn(session, session->IsKeepScreenOn());
9370 UpdatePrivateStateAndNotify(session->GetPersistentId());
9371 if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9372 ProcessSubSessionForeground(session);
9373 }
9374 session->SetPostProcessProperty(false);
9375 }
9376
9377 // update avoid area
9378 {
9379 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9380 for (auto& iter : sceneSessionMap_) {
9381 auto session = iter.second;
9382 if (session == nullptr) {
9383 continue;
9384 }
9385 session->PostProcessNotifyAvoidArea();
9386 }
9387 }
9388 }
9389
9390 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)9391 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
9392 {
9393 WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
9394 auto isSaCall = SessionPermission::IsSACalling();
9395 if (!isSaCall) {
9396 WLOGFE("The interface only support for sa call");
9397 return WSError::WS_ERROR_INVALID_PERMISSION;
9398 }
9399 auto task = [this, persistentId]() {
9400 auto sceneSession = GetSceneSession(persistentId);
9401 if (sceneSession == nullptr) {
9402 WLOGFE("session is nullptr");
9403 return WSError::WS_ERROR_INVALID_SESSION;
9404 }
9405 if (!IsSessionVisibleForeground(sceneSession)) {
9406 WLOGFD("session is not visible!");
9407 return WSError::WS_DO_NOTHING;
9408 }
9409 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
9410 RequestSessionFocus(persistentId, true, reason);
9411 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
9412 sceneSession->RaiseToAppTop();
9413 }
9414 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
9415 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
9416 WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
9417 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9418 }
9419 if (sceneSession == nullptr) {
9420 WLOGFE("parent session is nullptr");
9421 return WSError::WS_ERROR_INVALID_SESSION;
9422 }
9423 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9424 sceneSession->NotifyClick();
9425 return WSError::WS_OK;
9426 } else {
9427 WLOGFE("session is not app main window!");
9428 return WSError::WS_ERROR_INVALID_SESSION;
9429 }
9430 };
9431 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
9432 return WSError::WS_OK;
9433 }
9434
ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)9435 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
9436 {
9437 WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
9438 if (sourcePersistentId != focusedSessionId_) {
9439 WLOGFE("source session need be focused");
9440 return WSError::WS_ERROR_INVALID_OPERATION;
9441 }
9442 if (targetPersistentId == focusedSessionId_) {
9443 WLOGFE("target session has been focused");
9444 return WSError::WS_DO_NOTHING;
9445 }
9446 sptr<SceneSession> sourceSession = nullptr;
9447 WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
9448 if (ret != WSError::WS_OK) {
9449 return ret;
9450 }
9451 sptr<SceneSession> targetSession = nullptr;
9452 ret = GetAppMainSceneSession(targetSession, targetPersistentId);
9453 if (ret != WSError::WS_OK) {
9454 return ret;
9455 }
9456 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
9457 WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
9458 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
9459 return WSError::WS_ERROR_INVALID_CALLING;
9460 }
9461 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
9462 return WSError::WS_ERROR_INVALID_CALLING;
9463 }
9464 int32_t callingPid = IPCSkeleton::GetCallingPid();
9465 if (callingPid != targetSession->GetCallingPid()) {
9466 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
9467 return WSError::WS_ERROR_INVALID_CALLING;
9468 }
9469 targetSession->NotifyClick();
9470 FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
9471 return RequestSessionFocus(targetPersistentId, false, reason);
9472 }
9473
GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)9474 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
9475 {
9476 sceneSession = GetSceneSession(persistentId);
9477 if (sceneSession == nullptr) {
9478 WLOGFE("session(%{public}d) is nullptr", persistentId);
9479 return WSError::WS_ERROR_INVALID_SESSION;
9480 }
9481 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9482 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
9483 WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
9484 return WSError::WS_ERROR_INVALID_CALLING;
9485 }
9486 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9487 if (sceneSession == nullptr) {
9488 WLOGFE("session(%{public}d) parent is nullptr", persistentId);
9489 return WSError::WS_ERROR_INVALID_SESSION;
9490 }
9491 }
9492 return WSError::WS_OK;
9493 }
9494
GetSessionSnapshotPixelMap(const int32_t persistentId, const float scaleParam)9495 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
9496 const float scaleParam)
9497 {
9498 auto sceneSession = GetSceneSession(persistentId);
9499 if (!sceneSession) {
9500 WLOGFE("get scene session is nullptr");
9501 return nullptr;
9502 }
9503
9504 wptr<SceneSession> weakSceneSession(sceneSession);
9505 auto task = [this, persistentId, scaleParam, weakSceneSession]() {
9506 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
9507 auto scnSession = weakSceneSession.promote();
9508 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
9509 if (scnSession == nullptr) {
9510 WLOGFE("session is nullptr");
9511 return pixelMap;
9512 }
9513
9514 bool isPc = systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode();
9515 pixelMap = scnSession->Snapshot(false, scaleParam, isPc);
9516 if (!pixelMap) {
9517 WLOGFI("get local snapshot pixelmap start");
9518 pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
9519 }
9520 return pixelMap;
9521 };
9522 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
9523 }
9524
GetSceneSessionMap()9525 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
9526 {
9527 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
9528 {
9529 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9530 retSceneSessionMap = sceneSessionMap_;
9531 }
9532 EraseIf(retSceneSessionMap, [this](const auto& pair) {
9533 if (pair.second == nullptr) {
9534 return true;
9535 }
9536
9537 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
9538 if (pair.second->IsVisible()) {
9539 return false;
9540 }
9541 return true;
9542 }
9543
9544 if (pair.second->IsSystemInput()) {
9545 return false;
9546 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
9547 return false;
9548 }
9549
9550 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
9551 return true;
9552 }
9553 return false;
9554 });
9555 return retSceneSessionMap;
9556 }
9557
NotifyUpdateRectAfterLayout()9558 void SceneSessionManager::NotifyUpdateRectAfterLayout()
9559 {
9560 auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
9561 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
9562 if (transactionController) {
9563 rsTransaction = transactionController->GetRSTransaction();
9564 }
9565 auto task = [this, rsTransaction]() {
9566 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9567 for (const auto& iter: sceneSessionMap_) {
9568 auto sceneSession = iter.second;
9569 if (sceneSession && sceneSession->IsDirtyWindow()) {
9570 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
9571 }
9572 }
9573 };
9574 // need sync task since animation transcation need
9575 return taskScheduler_->PostAsyncTask(task, "NotifyUpdateRectAfterLayout");
9576 }
9577
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)9578 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
9579 {
9580 if (!SessionPermission::IsSystemCalling()) {
9581 WLOGFE("GetVisibilityWindowInfo permission denied!");
9582 return WMError::WM_ERROR_NOT_SYSTEM_APP;
9583 }
9584 auto task = [this, &infos]() {
9585 for (auto [surfaceId, _] : lastVisibleData_) {
9586 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9587 if (session == nullptr) {
9588 continue;
9589 }
9590 WSRect hostRect = session->GetSessionRect();
9591 Rect rect = {hostRect.posX_, hostRect.posY_,
9592 static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
9593 auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
9594 session->GetSessionProperty());
9595 infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
9596 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
9597 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_));
9598 }
9599 return WMError::WM_OK;
9600 };
9601 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
9602 }
9603
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)9604 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
9605 {
9606 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9607 for (const auto& [id, session] : sceneSessionMap_) {
9608 if (session == nullptr) {
9609 continue;
9610 }
9611 uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
9612 windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
9613 }
9614 }
9615
FlushWindowInfoToMMI(const bool forceFlush)9616 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
9617 {
9618 auto task = [this, forceFlush] {
9619 if (isUserBackground_) {
9620 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
9621 return;
9622 }
9623 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
9624 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
9625 };
9626 taskScheduler_->PostAsyncTask(task);
9627 }
9628
PostFlushWindowInfoTask(FlushWindowInfoTask &&task, const std::string taskName, const int delayTime)9629 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
9630 const std::string taskName, const int delayTime)
9631 {
9632 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
9633 }
9634
GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId, int32_t& parentId)9635 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
9636 int32_t& parentId)
9637 {
9638 // This function should be called in task
9639 auto iter = extSessionInfoMap_.find(token);
9640 if (iter == extSessionInfoMap_.end()) {
9641 return false;
9642 }
9643 persistentId = iter->second.persistentId;
9644 parentId = iter->second.parentId;
9645 return true;
9646 }
9647
DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)9648 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)
9649 {
9650 auto task = [this, remoteExtSession]() {
9651 auto iter = remoteExtSessionMap_.find(remoteExtSession);
9652 if (iter == remoteExtSessionMap_.end()) {
9653 TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
9654 return;
9655 }
9656 int32_t persistentId = INVALID_SESSION_ID;
9657 int32_t parentId = INVALID_SESSION_ID;
9658 if (!GetExtensionWindowIds(iter->second, persistentId, parentId)) {
9659 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9660 return;
9661 }
9662
9663 TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
9664 persistentId, parentId);
9665 auto sceneSession = GetSceneSession(parentId);
9666 if (sceneSession != nullptr) {
9667 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
9668 sceneSession->RemoveExtWindowFlags(persistentId);
9669 if (oldFlags.hideNonSecureWindowsFlag) {
9670 HandleSecureSessionShouldHide(sceneSession);
9671 }
9672 if (oldFlags.waterMarkFlag) {
9673 CheckAndNotifyWaterMarkChangedResult();
9674 }
9675 if (oldFlags.privacyModeFlag) {
9676 UpdatePrivateStateAndNotify(parentId);
9677 }
9678 sceneSession->RemoveModalUIExtension(persistentId);
9679 sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
9680 } else {
9681 ExtensionWindowFlags actions;
9682 actions.SetAllActive();
9683 HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
9684 }
9685 extSessionInfoMap_.erase(iter->second);
9686 remoteExtSessionMap_.erase(iter);
9687 };
9688 taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
9689 }
9690
UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)9691 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
9692 {
9693 auto pid = IPCSkeleton::GetCallingRealPid();
9694 auto task = [this, token, pid, rect]() {
9695 int32_t persistentId = INVALID_SESSION_ID;
9696 int32_t parentId = INVALID_SESSION_ID;
9697 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9698 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9699 return;
9700 }
9701 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
9702 "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
9703 pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
9704 auto parentSession = GetSceneSession(parentId);
9705 if (parentSession) {
9706 auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
9707 auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
9708 Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
9709 ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect };
9710 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
9711 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
9712 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
9713 parentSession->GetSessionGlobalRect().ToString().c_str());
9714 parentSession->UpdateModalUIExtension(extensionInfo);
9715 }
9716 };
9717 taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
9718 }
9719
ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)9720 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
9721 {
9722 auto pid = IPCSkeleton::GetCallingRealPid();
9723 auto task = [this, token, pid, posX, posY]() {
9724 int32_t persistentId = INVALID_SESSION_ID;
9725 int32_t parentId = INVALID_SESSION_ID;
9726 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9727 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
9728 return;
9729 }
9730 TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
9731 "parentId=%{public}d", pid, persistentId, parentId);
9732 auto parentSession = GetSceneSession(parentId);
9733 if (parentSession && parentSession->HasModalUIExtension()) {
9734 auto modalUIExtension = parentSession->GetLastModalUIExtensionEventInfo();
9735 if ((modalUIExtension.pid == pid) && (modalUIExtension.persistentId == persistentId)) {
9736 parentSession->ProcessPointDownSession(posX, posY);
9737 }
9738 }
9739 };
9740 taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
9741 }
9742
AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage, const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)9743 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
9744 const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)
9745 {
9746 auto pid = IPCSkeleton::GetCallingRealPid();
9747 auto task = [this, sessionStage, token, surfaceNodeId, pid]() {
9748 if (sessionStage == nullptr || token == nullptr) {
9749 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9750 return;
9751 }
9752 auto remoteExtSession = sessionStage->AsObject();
9753 if (remoteExtSession == nullptr) {
9754 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9755 return;
9756 }
9757 if (extensionDeath_ == nullptr) {
9758 TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
9759 return;
9760 }
9761 if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
9762 TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
9763 return;
9764 }
9765
9766 AAFwk::UIExtensionSessionInfo info;
9767 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
9768 if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
9769 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
9770 return;
9771 }
9772
9773 int32_t persistentId = info.persistentId;
9774 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
9775 UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
9776 TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
9777 "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
9778 surfaceNodeId, pid);
9779
9780 remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
9781 extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
9782
9783 auto parentSession = GetSceneSession(parentId);
9784 if (parentSession) {
9785 parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
9786 }
9787 if (usage == UIExtensionUsage::MODAL && parentSession) {
9788 ExtensionWindowEventInfo extensionInfo {
9789 .persistentId = persistentId,
9790 .pid = pid,
9791 };
9792 parentSession->AddModalUIExtension(extensionInfo);
9793 }
9794 };
9795 taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
9796 }
9797
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage, const sptr<IRemoteObject>& token)9798 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
9799 const sptr<IRemoteObject>& token)
9800 {
9801 TLOGI(WmsLogTag::WMS_UIEXT, "called");
9802 auto task = [this, sessionStage, token]() {
9803 if (sessionStage == nullptr || token == nullptr) {
9804 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
9805 return;
9806 }
9807 auto remoteExtSession = sessionStage->AsObject();
9808 if (remoteExtSession == nullptr) {
9809 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
9810 return;
9811 }
9812 auto iter = remoteExtSessionMap_.find(remoteExtSession);
9813 if (iter->second != token) {
9814 TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
9815 return;
9816 }
9817
9818 DestroyExtensionSession(remoteExtSession);
9819 };
9820 taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
9821 }
9822
CalculateCombinedExtWindowFlags()9823 void SceneSessionManager::CalculateCombinedExtWindowFlags()
9824 {
9825 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
9826 combinedExtWindowFlags_.bitData = 0;
9827 for (const auto& iter: extWindowFlagsMap_) {
9828 combinedExtWindowFlags_.bitData |= iter.second.bitData;
9829 }
9830 specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
9831 }
9832
UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags, ExtensionWindowFlags actions)9833 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
9834 ExtensionWindowFlags actions)
9835 {
9836 auto iter = extWindowFlagsMap_.find(persistentId);
9837 // Each flag is false when inactive, 0 means all flags are inactive
9838 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
9839 ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
9840 if (newFlags.bitData == 0) {
9841 extWindowFlagsMap_.erase(persistentId);
9842 } else {
9843 extWindowFlagsMap_[persistentId] = newFlags;
9844 }
9845 CalculateCombinedExtWindowFlags();
9846 }
9847
HideNonSecureFloatingWindows()9848 void SceneSessionManager::HideNonSecureFloatingWindows()
9849 {
9850 bool shouldHide = false;
9851 {
9852 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9853 for (const auto& iter: sceneSessionMap_) {
9854 auto& session = iter.second;
9855 if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
9856 shouldHide = true;
9857 break;
9858 }
9859 }
9860 }
9861 if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
9862 TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
9863 shouldHide = true;
9864 }
9865 if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
9866 return;
9867 }
9868
9869 shouldHideNonSecureFloatingWindows_.store(shouldHide);
9870 for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
9871 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
9872 session->NotifyForceHideChange(shouldHide);
9873 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9874 session->GetWindowName().c_str(), persistentId, shouldHide);
9875 }
9876 }
9877 }
9878
HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)9879 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
9880 {
9881 // don't let sub-window show when switching secure host window to background
9882 if (!sceneSession->IsSessionForeground()) {
9883 return;
9884 }
9885
9886 auto parentId = sceneSession->GetPersistentId();
9887 bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
9888 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9889 for (const auto& [persistentId, session] : sceneSessionMap_) {
9890 if (!session) {
9891 continue;
9892 }
9893 auto property = session->GetSessionProperty();
9894 if (!property || property->GetParentPersistentId() != parentId) {
9895 continue;
9896 }
9897
9898 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
9899 session->NotifyForceHideChange(shouldHide);
9900 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
9901 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
9902 }
9903 }
9904 }
9905
HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)9906 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
9907 {
9908 if (sceneSession == nullptr) {
9909 TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
9910 return WSError::WS_ERROR_INVALID_SESSION;
9911 }
9912
9913 HideNonSecureFloatingWindows();
9914 HideNonSecureSubWindows(sceneSession);
9915 return WSError::WS_OK;
9916 }
9917
HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags, ExtensionWindowFlags actions)9918 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
9919 ExtensionWindowFlags actions)
9920 {
9921 UpdateSpecialExtWindowFlags(persistentId, flags, actions);
9922 if (actions.waterMarkFlag) {
9923 CheckAndNotifyWaterMarkChangedResult();
9924 }
9925 if (actions.hideNonSecureWindowsFlag) {
9926 HideNonSecureFloatingWindows();
9927 }
9928 if (actions.privacyModeFlag) {
9929 UpdatePrivateStateAndNotifyForAllScreens();
9930 }
9931 }
9932
AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)9933 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
9934 {
9935 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
9936 if (!SessionPermission::IsSystemCalling()) {
9937 TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
9938 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9939 }
9940 const auto callingPid = IPCSkeleton::GetCallingRealPid();
9941 auto task = [this, persistentId, shouldHide, callingPid]() {
9942 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9943 auto iter = sceneSessionMap_.find(persistentId);
9944 if (iter == sceneSessionMap_.end()) {
9945 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
9946 persistentId);
9947 return WSError::WS_ERROR_INVALID_SESSION;
9948 }
9949 auto sceneSession = iter->second;
9950 if (sceneSession == nullptr) {
9951 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
9952 return WSError::WS_ERROR_NULLPTR;
9953 }
9954 if (callingPid != sceneSession->GetCallingPid()) {
9955 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
9956 return WSError::WS_ERROR_INVALID_PERMISSION;
9957 }
9958 sceneSession->SetShouldHideNonSecureWindows(shouldHide);
9959 return HandleSecureSessionShouldHide(sceneSession);
9960 };
9961
9962 taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
9963 return WSError::WS_OK;
9964 }
9965
CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const9966 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
9967 {
9968 auto ret = WSError::WS_OK;
9969 bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
9970 if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
9971 actions.hideNonSecureWindowsFlag = false;
9972 actions.waterMarkFlag = false;
9973 TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
9974 ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
9975 }
9976 auto needPrivacyWindow = actions.privacyModeFlag;
9977 if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
9978 actions.privacyModeFlag = false;
9979 TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
9980 ret = WSError::WS_ERROR_INVALID_PERMISSION;
9981 }
9982 return ret;
9983 }
9984
UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags, uint32_t extWindowActions)9985 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
9986 uint32_t extWindowActions)
9987 {
9988 ExtensionWindowFlags actions(extWindowActions);
9989 auto ret = CheckExtWindowFlagsPermission(actions);
9990 if (actions.bitData == 0) {
9991 return ret;
9992 }
9993
9994 ExtensionWindowFlags flags(extWindowFlags);
9995 auto task = [this, token, flags, actions]() {
9996 int32_t persistentId = INVALID_SESSION_ID;
9997 int32_t parentId = INVALID_SESSION_ID;
9998 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
9999 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10000 return WSError::WS_ERROR_INVALID_OPERATION;
10001 }
10002
10003 TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
10004 "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
10005 auto sceneSession = GetSceneSession(parentId);
10006 if (sceneSession == nullptr) {
10007 TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
10008 parentId);
10009 HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
10010 return WSError::WS_OK;
10011 }
10012
10013 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10014 sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
10015 auto newFlags = sceneSession->GetCombinedExtWindowFlags();
10016 if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
10017 HandleSecureSessionShouldHide(sceneSession);
10018 }
10019 if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
10020 CheckAndNotifyWaterMarkChangedResult();
10021 }
10022 if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
10023 UpdatePrivateStateAndNotify(parentId);
10024 }
10025 return WSError::WS_OK;
10026 };
10027
10028 taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
10029 return ret;
10030 }
10031
ReportWindowProfileInfos()10032 void SceneSessionManager::ReportWindowProfileInfos()
10033 {
10034 enum class WindowVisibleState : int32_t {
10035 FOCUSBLE = 0,
10036 VISIBLE,
10037 MINIMIZED,
10038 OCCLUSION
10039 };
10040 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10041 {
10042 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10043 sceneSessionMapCopy = sceneSessionMap_;
10044 }
10045 auto focusWindowId = GetFocusedSessionId();
10046 for (const auto& elem : sceneSessionMapCopy) {
10047 auto curSession = elem.second;
10048 if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10049 curSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10050 continue;
10051 }
10052 WindowProfileInfo windowProfileInfo;
10053 windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10054 windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10055 curSession->GetSessionProperty()->GetDisplayId());
10056 windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10057 if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10058 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10059 } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10060 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10061 } else if (!curSession->GetRSVisible()) {
10062 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10063 } else {
10064 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10065 }
10066 WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10067 WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10068 "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10069 windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10070 windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10071 }
10072 }
10073
IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo, const std::vector<VisibleWindowNumInfo>& currentInfo)10074 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
10075 const std::vector<VisibleWindowNumInfo>& currentInfo)
10076 {
10077 if (lastInfo.size() != currentInfo.size()) {
10078 WLOGFE("last and current info is not Same");
10079 return false;
10080 }
10081 size_t sizeOfLastInfo = lastInfo.size();
10082 for (size_t i = 0; i < sizeOfLastInfo; i++) {
10083 if (lastInfo[i].displayId != currentInfo[i].displayId ||
10084 lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
10085 WLOGFE("last and current visible window num is not Same");
10086 return false;
10087 }
10088 }
10089 return true;
10090 }
10091
GetDisplayIdByPersistentId(int32_t persistentId, int32_t& displayId)10092 WMError SceneSessionManager::GetDisplayIdByPersistentId(int32_t persistentId, int32_t& displayId)
10093 {
10094 auto task = [this, persistentId, &displayId]() {
10095 sptr<SceneSession> session = GetSceneSession(persistentId);
10096 if (session == nullptr) {
10097 TLOGE(WmsLogTag::WMS_MAIN, "GetDisplayIdByPersistentId: session is nullptr");
10098 return WMError::WM_ERROR_INVALID_SESSION;
10099 }
10100 sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
10101 if (sessionProperty == nullptr) {
10102 TLOGE(WmsLogTag::WMS_MAIN, "GetDisplayIdByPersistentId: sessionProperty is nullptr");
10103 return WMError::WM_ERROR_INVALID_SESSION;
10104 }
10105 displayId = static_cast<int32_t>(sessionProperty->GetDisplayId());
10106 return WMError::WM_OK;
10107 };
10108 return taskScheduler_->PostSyncTask(task, "GetDisplayIdByPersistentId");
10109 }
10110
CacVisibleWindowNum()10111 void SceneSessionManager::CacVisibleWindowNum()
10112 {
10113 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10114 {
10115 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10116 sceneSessionMapCopy = sceneSessionMap_;
10117 }
10118 std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
10119 bool isFullScreen = true;
10120 for (const auto& elem : sceneSessionMapCopy) {
10121 auto curSession = elem.second;
10122 if (curSession == nullptr) {
10123 continue;
10124 }
10125 bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
10126 curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
10127 if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10128 continue;
10129 }
10130
10131 bool isWindowVisible = curSession->GetRSVisible();
10132 if (isWindowVisible) {
10133 auto windowMode = curSession->GetWindowMode();
10134 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
10135 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
10136 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
10137 isFullScreen = false;
10138 }
10139 uint32_t displayId = static_cast<uint32_t>(curSession->GetSessionProperty()->GetDisplayId());
10140 auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10141 [=](const VisibleWindowNumInfo& info) {
10142 return info.displayId == displayId;
10143 });
10144 if (it == visibleWindowNumInfo.end()) {
10145 visibleWindowNumInfo.push_back({displayId, 1});
10146 } else {
10147 it->visibleWindowNum++;
10148 }
10149 }
10150 }
10151 if (isFullScreen) {
10152 std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10153 [](auto& info) { info.visibleWindowNum = 1; });
10154 }
10155 std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
10156 if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10157 SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10158 lastInfo_ = visibleWindowNumInfo;
10159 }
10160 }
10161
GetHostWindowRect(int32_t hostWindowId, Rect& rect)10162 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
10163 {
10164 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
10165 if (!SessionPermission::IsSystemCalling()) {
10166 TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
10167 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10168 }
10169 auto task = [this, hostWindowId, &rect]() {
10170 auto sceneSession = GetSceneSession(hostWindowId);
10171 if (sceneSession == nullptr) {
10172 TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
10173 return WSError::WS_ERROR_INVALID_SESSION;
10174 }
10175 WSRect hostRect = sceneSession->GetSessionRect();
10176 rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
10177 return WSError::WS_OK;
10178 };
10179 taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
10180 return WSError::WS_OK;
10181 }
10182
GetDisplayRegion(DisplayId displayId)10183 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10184 {
10185 if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10186 return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10187 }
10188 TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10189 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10190 if (display == nullptr) {
10191 TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10192 return nullptr;
10193 }
10194 auto displayInfo = display->GetDisplayInfo();
10195 if (displayInfo == nullptr) {
10196 TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
10197 return nullptr;
10198 }
10199 int32_t displayWidth = displayInfo->GetWidth();
10200 int32_t displayHeight = displayInfo->GetHeight();
10201 if (displayWidth == 0 || displayHeight == 0) {
10202 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10203 return nullptr;
10204 }
10205
10206 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10207 auto region = std::make_shared<SkRegion>(rect);
10208 displayRegionMap_[displayId] = region;
10209 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10210 return std::make_shared<SkRegion>(rect);
10211 }
10212
UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)10213 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
10214 {
10215 if (displayInfo == nullptr) {
10216 TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
10217 return;
10218 }
10219 auto displayId = displayInfo->GetDisplayId();
10220 int32_t displayWidth = displayInfo->GetWidth();
10221 int32_t displayHeight = displayInfo->GetHeight();
10222 if (displayWidth == 0 || displayHeight == 0) {
10223 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10224 return;
10225 }
10226 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10227 auto region = std::make_shared<SkRegion>(rect);
10228 displayRegionMap_[displayId] = region;
10229 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10230 }
10231
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)10232 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
10233 {
10234 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10235 for (const auto& item : sceneSessionMap_) {
10236 auto sceneSession = item.second;
10237 if (sceneSession == nullptr) {
10238 continue;
10239 }
10240 if (Session::IsScbCoreEnabled()) {
10241 if (!sceneSession->IsVisibleForAccessibility()) {
10242 continue;
10243 }
10244 } else {
10245 if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
10246 continue;
10247 }
10248 }
10249 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10250 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10251 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10252 continue;
10253 }
10254 sceneSessionList.push_back(sceneSession);
10255 }
10256 }
10257
FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList, std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)10258 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
10259 std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
10260 {
10261 for (const auto& sceneSession : sceneSessionList) {
10262 if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
10263 TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
10264 }
10265 }
10266 }
10267
FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)10268 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
10269 {
10270 std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
10271 return a->GetZOrder() > b->GetZOrder();
10272 });
10273 std::vector<sptr<SceneSession>> result;
10274 std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
10275 for (const auto& sceneSession : sceneSessionList) {
10276 if (sceneSession == nullptr) {
10277 TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
10278 continue;
10279 }
10280 auto sessionProperty = sceneSession->GetSessionProperty();
10281 if (sessionProperty == nullptr) {
10282 TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
10283 continue;
10284 }
10285 std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
10286 auto displayId = sessionProperty->GetDisplayId();
10287 if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
10288 unaccountedSpace = unaccountedSpaceMap[displayId];
10289 } else {
10290 unaccountedSpace = GetDisplayRegion(displayId);
10291 if (unaccountedSpace == nullptr) {
10292 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
10293 continue;
10294 }
10295 unaccountedSpaceMap[displayId] = unaccountedSpace;
10296 }
10297 WSRect wsRect = sceneSession->GetSessionRect();
10298 SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
10299 .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
10300 SkRegion windowRegion(windowBounds);
10301 if (unaccountedSpace->quickReject(windowRegion)) {
10302 TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10303 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10304 continue;
10305 }
10306 if (!unaccountedSpace->intersects(windowRegion)) {
10307 TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10308 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10309 continue;
10310 }
10311 result.push_back(sceneSession);
10312 unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
10313 if (unaccountedSpace->isEmpty()) {
10314 break;
10315 }
10316 }
10317 sceneSessionList = result;
10318 }
10319
NotifyAllAccessibilityInfo()10320 void SceneSessionManager::NotifyAllAccessibilityInfo()
10321 {
10322 if (isUserBackground_) {
10323 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
10324 return;
10325 }
10326 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::NotifyAllAccessibilityInfo");
10327 std::vector<sptr<SceneSession>> sceneSessionList;
10328 GetAllSceneSessionForAccessibility(sceneSessionList);
10329 FilterSceneSessionCovered(sceneSessionList);
10330
10331 std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
10332 FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
10333
10334 for (const auto& item : accessibilityInfo) {
10335 TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, "
10336 "bundle=%{public}s,bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
10337 item->wid_, item->innerWid_, item->bundleName_.c_str(),
10338 item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
10339 for (const auto& rect : item->touchHotAreas_) {
10340 TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d,"
10341 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
10342 }
10343 }
10344
10345 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
10346 WindowUpdateType::WINDOW_UPDATE_ALL);
10347 }
10348
RemoveFailRecoveredSession()10349 void SceneSessionManager::RemoveFailRecoveredSession()
10350 {
10351 for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10352 auto sceneSession = GetSceneSession(persistentId);
10353 if (sceneSession == nullptr) {
10354 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10355 continue;
10356 }
10357 if (!sceneSession->IsRecovered()) {
10358 TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10359 continue;
10360 }
10361 const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10362 if (!scnSessionInfo) {
10363 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr, persistentId = %{public}d", persistentId);
10364 continue;
10365 }
10366 TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10367 sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10368 }
10369 failRecoveredPersistentIdSet_.clear();
10370 }
10371
ReclaimPurgeableCleanMem()10372 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
10373 {
10374 #ifdef MEMMGR_WINDOW_ENABLE
10375 return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
10376 #else
10377 return -1;
10378 #endif
10379 }
10380
GetWindowStatus(WindowMode mode, SessionState sessionState, const sptr<WindowSessionProperty>& property)10381 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
10382 const sptr<WindowSessionProperty>& property)
10383 {
10384 auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
10385 if (property == nullptr) {
10386 return windowStatus;
10387 }
10388 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
10389 windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
10390 if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
10391 windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
10392 }
10393 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
10394 windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
10395 } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
10396 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10397 } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
10398 windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
10399 }
10400 return windowStatus;
10401 }
10402
GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)10403 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
10404 {
10405 if (!SessionPermission::IsStartedByInputMethod()) {
10406 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10407 return WMError::WM_ERROR_INVALID_PERMISSION;
10408 }
10409 auto scnSession = GetSceneSession(persistentId);
10410 if (scnSession == nullptr) {
10411 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10412 return WMError::WM_ERROR_NULLPTR;
10413 }
10414
10415 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10416 persistentId, scnSession->GetWindowType());
10417
10418 auto sessionProperty = scnSession->GetSessionProperty();
10419 if (sessionProperty == nullptr) {
10420 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10421 return WMError::WM_ERROR_INVALID_WINDOW;
10422 }
10423 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10424 auto callingSession = GetSceneSession(callingWindowId);
10425 if (callingSession == nullptr) {
10426 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10427 callingSession = GetSceneSession(focusedSessionId_);
10428 if (callingSession == nullptr) {
10429 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10430 return WMError::WM_ERROR_INVALID_WINDOW;
10431 }
10432 }
10433 if (callingSession->IsSystemSession()) {
10434 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10435 } else {
10436 windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
10437 callingSession->GetSessionProperty());
10438 }
10439 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
10440 persistentId, windowStatus);
10441 return WMError::WM_OK;
10442 }
10443
GetCallingWindowRect(int32_t persistentId, Rect& rect)10444 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
10445 {
10446 if (!SessionPermission::IsStartedByInputMethod()) {
10447 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10448 return WMError::WM_ERROR_INVALID_PERMISSION;
10449 }
10450 auto scnSession = GetSceneSession(persistentId);
10451 if (scnSession == nullptr) {
10452 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10453 return WMError::WM_ERROR_NULLPTR;
10454 }
10455 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10456 persistentId, scnSession->GetWindowType());
10457 auto sessionProperty = scnSession->GetSessionProperty();
10458 if (sessionProperty == nullptr) {
10459 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10460 return WMError::WM_ERROR_INVALID_WINDOW;
10461 }
10462 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10463 auto callingSession = GetSceneSession(callingWindowId);
10464 if (callingSession == nullptr) {
10465 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10466 callingSession = GetSceneSession(focusedSessionId_);
10467 if (callingSession == nullptr) {
10468 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10469 return WMError::WM_ERROR_INVALID_WINDOW;
10470 }
10471 }
10472 WSRect sessionRect = callingSession->GetSessionRect();
10473 rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
10474 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
10475 "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10476 return WMError::WM_OK;
10477 }
10478
GetWindowModeType(WindowModeType& windowModeType)10479 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
10480 {
10481 if (!SessionPermission::IsSACalling()) {
10482 WLOGFE("GetWindowModeType permission denied!");
10483 return WMError::WM_ERROR_INVALID_PERMISSION;
10484 }
10485 windowModeType = CheckWindowModeType();
10486 return WMError::WM_OK;
10487 }
10488
GetWindowStyleType(WindowStyleType& windowStyleType)10489 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
10490 {
10491 if (!SessionPermission::IsSACalling()) {
10492 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10493 return WMError::WM_ERROR_INVALID_PERMISSION;
10494 }
10495 if (systemConfig_.IsPcWindow()) {
10496 windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
10497 return WMError::WM_OK;
10498 }
10499 windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
10500 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
10501 return WMError::WM_OK;
10502 }
10503
CheckSceneZOrder()10504 void SceneSessionManager::CheckSceneZOrder()
10505 {
10506 auto task = [this]() {
10507 AnomalyDetection::SceneZOrderCheckProcess();
10508 };
10509 taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
10510 }
10511
GetCustomDecorHeight(int32_t persistentId)10512 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10513 {
10514 int32_t height = 0;
10515 auto sceneSession = GetSceneSession(persistentId);
10516 if (sceneSession == nullptr) {
10517 TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10518 return 0;
10519 }
10520 height = sceneSession->GetCustomDecorHeight();
10521 TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10522 return height;
10523 }
10524
GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)10525 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
10526 {
10527 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
10528 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
10529 return WMError::WM_ERROR_INVALID_PERMISSION;
10530 }
10531
10532 if (!topNInfo.empty() || (topNum <= 0)) {
10533 return WMError::WM_ERROR_INVALID_PARAM;
10534 }
10535
10536 TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
10537 auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
10538 if (session == nullptr) {
10539 return false;
10540 }
10541
10542 if (topNum == 0) {
10543 return true;
10544 }
10545
10546 if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
10547 TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
10548 return false;
10549 }
10550
10551 MainWindowInfo info;
10552 info.pid_ = session->GetCallingPid();
10553 info.bundleName_ = session->GetSessionInfo().bundleName_;
10554 topNInfo.push_back(info);
10555 topNum--;
10556 TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
10557 topNum, info.pid_, info.bundleName_.c_str());
10558 return false;
10559 };
10560 TraverseSessionTree(func, true);
10561
10562 return WMError::WM_OK;
10563 }
10564
GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber, int32_t x, int32_t y, std::vector<int32_t>& windowIds)10565 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
10566 int32_t x, int32_t y, std::vector<int32_t>& windowIds)
10567 {
10568 TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
10569 displayId, windowNumber, x, y);
10570 if (displayId == DISPLAY_ID_INVALID) {
10571 TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
10572 return WMError::WM_ERROR_INVALID_PARAM;
10573 }
10574 bool findAllWindow = windowNumber <= 0;
10575 bool checkPoint = (x >= 0 && y >= 0);
10576 std::string callerBundleName = SessionPermission::GetCallingBundleName();
10577 auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
10578 findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
10579 if (session == nullptr) {
10580 return false;
10581 }
10582 auto sessionProperty = session->GetSessionProperty();
10583 if (sessionProperty == nullptr) {
10584 return false;
10585 }
10586 if (!findAllWindow && windowNumber == 0) {
10587 return true;
10588 }
10589 bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
10590 bool isSameDisplayId = sessionProperty->GetDisplayId() == displayId;
10591 bool isRsVisible = session->GetRSVisible();
10592 WSRect windowRect = session->GetSessionRect();
10593 bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
10594 TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
10595 " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
10596 session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
10597 sessionProperty->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
10598 if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
10599 return false;
10600 }
10601 windowIds.emplace_back(session->GetPersistentId());
10602 windowNumber--;
10603 return false;
10604 };
10605 auto task = [this, func = std::move(func)] {
10606 TraverseSessionTree(func, true);
10607 return WMError::WM_OK;
10608 };
10609 return taskScheduler_->PostSyncTask(task, __func__);
10610 }
10611
NotifyEnterRecentTask(bool enterRecent)10612 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
10613 {
10614 TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
10615 enterRecent_.store(enterRecent);
10616 SetSystemAnimatedScenes(enterRecent ?
10617 SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
10618 auto task = [this] {
10619 for (auto persistentId : gestureBackEnableWindowIdSet_) {
10620 auto sceneSession = GetSceneSession(persistentId);
10621 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
10622 continue;
10623 }
10624 UpdateGestureBackEnabled(persistentId);
10625 }
10626 };
10627 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
10628 return WSError::WS_OK;
10629 }
10630
GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const10631 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
10632 {
10633 if (!infos.empty()) {
10634 TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
10635 return WMError::WM_ERROR_INVALID_PARAM;
10636 }
10637 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10638 TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
10639 return WMError::WM_ERROR_INVALID_PERMISSION;
10640 }
10641 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10642 for (const auto& iter : sceneSessionMap_) {
10643 auto& session = iter.second;
10644 if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
10645 continue;
10646 }
10647 MainWindowInfo info;
10648 auto abilityInfo = session->GetSessionInfo().abilityInfo;
10649 info.pid_ = session->GetCallingPid();
10650 info.bundleName_ = session->GetSessionInfo().bundleName_;
10651 info.persistentId_ = session->GetPersistentId();
10652 if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
10653 TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
10654 info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
10655 infos.push_back(info);
10656 } else if (abilityInfo != nullptr) {
10657 info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
10658 infos.push_back(info);
10659 TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d,"
10660 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
10661 info.bundleName_.c_str(), info.bundleType_);
10662 }
10663 }
10664 return WMError::WM_OK;
10665 }
10666
ClearMainSessions(const std::vector<int32_t>& persistentIds, std::vector<int32_t>& clearFailedIds)10667 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
10668 std::vector<int32_t>& clearFailedIds)
10669 {
10670 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10671 TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
10672 return WMError::WM_ERROR_INVALID_PERMISSION;
10673 }
10674 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
10675 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
10676 return WMError::WM_ERROR_INVALID_PERMISSION;
10677 }
10678 clearFailedIds.clear();
10679 for (const auto persistentId : persistentIds) {
10680 auto sceneSession = GetSceneSession(persistentId);
10681 if (sceneSession == nullptr) {
10682 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
10683 clearFailedIds.push_back(persistentId);
10684 continue;
10685 }
10686 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10687 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10688 clearFailedIds.push_back(persistentId);
10689 continue;
10690 }
10691 sceneSession->Clear();
10692 TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
10693 }
10694 return WMError::WM_OK;
10695 }
10696
UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density, bool enable)10697 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
10698 bool enable)
10699 {
10700 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
10701 width, height, density, enable);
10702
10703 DMHookInfo dmHookInfo;
10704 dmHookInfo.width_ = width;
10705 dmHookInfo.height_ = height;
10706 dmHookInfo.density_ = density;
10707 dmHookInfo.rotation_ = 0;
10708 dmHookInfo.enableHookRotation_ = false;
10709 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10710 return WMError::WM_OK;
10711 }
10712
UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)10713 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
10714 {
10715 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
10716 "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
10717 hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
10718 if (enable && (uid <= 0 || hookInfo.width_ <= 0 || hookInfo.height_ <= 0 || hookInfo.density_ <= 0)) {
10719 TLOGE(WmsLogTag::WMS_LAYOUT, "App hookInfo param error.");
10720 return WMError::WM_ERROR_INVALID_PARAM;
10721 }
10722 DMHookInfo dmHookInfo;
10723 dmHookInfo.width_ = hookInfo.width_;
10724 dmHookInfo.height_ = hookInfo.height_;
10725 dmHookInfo.density_ = hookInfo.density_;
10726 dmHookInfo.rotation_ = hookInfo.rotation_;
10727 dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
10728 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
10729 return WMError::WM_OK;
10730 }
10731
OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)10732 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
10733 {
10734 SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
10735 }
10736
ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)10737 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
10738 {
10739 ScreenFoldData screenFoldData;
10740 WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
10741 if (ret != WMError::WM_OK) {
10742 return ret;
10743 }
10744 return CheckAndReportScreenFoldStatus(screenFoldData);
10745 }
10746
MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo, ScreenFoldData& screenFoldData)10747 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
10748 ScreenFoldData& screenFoldData)
10749 {
10750 if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
10751 TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
10752 return WMError::WM_DO_NOTHING;
10753 }
10754
10755 screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
10756 screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
10757 screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
10758 screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
10759 screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
10760 if (!screenFoldData.GetTypeCThermalWithUtil()) {
10761 TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
10762 return WMError::WM_DO_NOTHING;
10763 }
10764 AppExecFwk::ElementName element = {};
10765 WSError ret = GetFocusSessionElement(element);
10766 if (ret != WSError::WS_OK) {
10767 TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
10768 return WMError::WM_DO_NOTHING;
10769 }
10770 screenFoldData.SetFocusedPkgName(element.GetURI());
10771 int32_t ret_z = HiSysEventWrite(
10772 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
10773 "FOCUS_WINDOW",
10774 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
10775 "BUNDLE_NAME", element.GetURI());
10776 if (ret_z != 0) {
10777 TLOGE(WmsLogTag::DMS, "Write FOCUS_WINDOW HiSysEvent error, ret_z: %{public}d.", ret_z);
10778 }
10779 return WMError::WM_OK;
10780 }
10781
CheckAndReportScreenFoldStatus(ScreenFoldData& data)10782 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
10783 {
10784 static ScreenFoldData lastScreenHalfFoldData;
10785 if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10786 lastScreenHalfFoldData = data;
10787 return WMError::WM_DO_NOTHING;
10788 }
10789 WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
10790 if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
10791 if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
10792 lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
10793 } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
10794 // if stay at half-fold less than 15s, combine this change with last
10795 data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
10796 data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
10797 data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
10798 }
10799 lastScreenHalfFoldData.SetInvalid();
10800 }
10801 WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
10802 return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
10803 currentScreenFoldStatusReportRet;
10804 }
10805
10806 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData& data)10807 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
10808 {
10809 if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
10810 return WMError::WM_DO_NOTHING;
10811 }
10812
10813 int32_t ret = HiSysEventWrite(
10814 OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
10815 "FOLDSCREEN_STATE_CHANGE",
10816 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
10817 "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
10818 "LASTFOLDSTATE", data.currentScreenFoldStatus_,
10819 "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
10820 "STATE", -1,
10821 "TIME", data.currentScreenFoldStatusDuration_,
10822 "ROTATION", data.screenRotation_,
10823 "PACKAGE", data.focusedPackageName_,
10824 "ANGLE", data.postureAngle_,
10825 "TYPECTHERMAL", data.typeCThermal_,
10826 "SCREENTHERMAL", -1,
10827 "SCANGLE", -1,
10828 "ISTENT", -1);
10829 if (ret != 0) {
10830 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
10831 return WMError::WM_DO_NOTHING;
10832 }
10833 return WMError::WM_OK;
10834 }
10835
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)10836 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
10837 {
10838 if (currentUserId_ != static_cast<int32_t>(userid)) {
10839 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64"", currentUserId_, userid);
10840 return;
10841 }
10842 auto secSurfaceInfoMap = secExtensionData->GetSecData();
10843 auto task = [secSurfaceInfoMap]()-> WSError {
10844 SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
10845 return WSError::WS_OK;
10846 };
10847 taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
10848 }
10849
RegisterSecSurfaceInfoListener()10850 void SceneSessionManager::RegisterSecSurfaceInfoListener()
10851 {
10852 auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
10853 this->UpdateSecSurfaceInfo(secExtensionData, userid);
10854 };
10855 TLOGI(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener");
10856 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
10857 TLOGE(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener failed");
10858 }
10859 }
10860
SetAppForceLandscapeConfig(const std::string& bundleName, const AppForceLandscapeConfig& config)10861 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
10862 const AppForceLandscapeConfig& config)
10863 {
10864 if (bundleName.empty()) {
10865 TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
10866 return WSError::WS_ERROR_NULLPTR;
10867 }
10868 std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10869 appForceLandscapeMap_[bundleName] = config;
10870 TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
10871 bundleName.c_str(), config.mode_, config.homePage_.c_str());
10872 return WSError::WS_OK;
10873 }
10874
GetAppForceLandscapeConfig(const std::string& bundleName)10875 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
10876 {
10877 if (bundleName.empty()) {
10878 return {};
10879 }
10880 std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
10881 if (appForceLandscapeMap_.empty() ||
10882 appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
10883 TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
10884 return {};
10885 }
10886 return appForceLandscapeMap_[bundleName];
10887 }
10888
TerminateSessionByPersistentId(int32_t persistentId)10889 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
10890 {
10891 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS) ||
10892 !SessionPermission::IsSystemAppCall()) {
10893 TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
10894 return WMError::WM_ERROR_INVALID_PERMISSION;
10895 }
10896 auto sceneSession = GetSceneSession(persistentId);
10897 if (sceneSession == nullptr) {
10898 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
10899 return WMError::WM_ERROR_INVALID_PARAM;
10900 }
10901 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
10902 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
10903 return WMError::WM_ERROR_INVALID_PARAM;
10904 }
10905 sceneSession->Clear(true);
10906 TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
10907 return WMError::WM_OK;
10908 }
10909
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)10910 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
10911 {
10912 rootSceneProcessBackEventFunc_ = processBackEventFunc;
10913 TLOGI(WmsLogTag::WMS_EVENT, "called");
10914 }
10915
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid, const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)10916 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
10917 const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
10918 {
10919 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
10920 TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
10921 return WMError::WM_ERROR_INVALID_PERMISSION;
10922 }
10923
10924 surfaceNodeIds.clear();
10925 TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
10926 for (auto persistentId : persistentIds) {
10927 TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
10928 auto sceneSession = GetSceneSession(persistentId);
10929 if (sceneSession == nullptr) {
10930 continue;
10931 }
10932 auto callingPid = sceneSession->GetCallingPid();
10933 auto surfaceNode = sceneSession->GetSurfaceNode();
10934 if (surfaceNode != nullptr && callingPid == pid) {
10935 surfaceNodeIds.push_back(surfaceNode->GetId());
10936 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
10937 if (leashWinSurfaceNode != nullptr) {
10938 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
10939 surfaceNodeIds.push_back(persistentId);
10940 }
10941 }
10942 }
10943
10944 return WMError::WM_OK;
10945 }
10946
RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)10947 void SceneSessionManager::RefreshPcZOrderList(uint32_t startZOrder, std::vector<int32_t>&& persistentIds)
10948 {
10949 auto task = [this, startZOrder, persistentIds = std::move(persistentIds)] {
10950 std::ostringstream oss;
10951 oss << "[";
10952 for (size_t i = 0; i < persistentIds.size(); i++) {
10953 int32_t persistentId = persistentIds[i];
10954 oss << persistentId;
10955 if (i < persistentIds.size() - 1) {
10956 oss << ",";
10957 }
10958 auto sceneSession = GetSceneSession(persistentId);
10959 if (sceneSession == nullptr) {
10960 TLOGNE(WmsLogTag::WMS_LAYOUT, "sceneSession is nullptr persistentId = %{public}d", persistentId);
10961 continue;
10962 }
10963 if (i > UINT32_MAX - startZOrder) {
10964 TLOGNE(WmsLogTag::WMS_LAYOUT, "Z order overflow, stop refresh");
10965 break;
10966 }
10967 sceneSession->SetPcScenePanel(true);
10968 sceneSession->PcUpdateZOrderAndDirty(i + startZOrder);
10969 }
10970 oss << "]";
10971 TLOGNI(WmsLogTag::WMS_LAYOUT, "RefreshPcZOrderList:%{public}s", oss.str().c_str());
10972 return WSError::WS_OK;
10973 };
10974 taskScheduler_->PostTask(task, __func__);
10975 }
10976
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)10977 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
10978 {
10979 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
10980 closeTargetFloatWindowFunc_ = func;
10981 }
10982
CloseTargetFloatWindow(const std::string& bundleName)10983 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
10984 {
10985 if (!SessionPermission::IsSystemServiceCalling(false)) {
10986 TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
10987 return WMError::WM_ERROR_INVALID_PERMISSION;
10988 }
10989 auto task = [this, bundleName] {
10990 if (closeTargetFloatWindowFunc_) {
10991 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
10992 closeTargetFloatWindowFunc_(bundleName);
10993 }
10994 };
10995 taskScheduler_->PostTask(task, "CloseTargetFloatWindow");
10996 return WMError::WM_OK;
10997 }
10998
UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)10999 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
11000 {
11001 SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
11002 }
11003
CloseTargetPiPWindow(const std::string& bundleName)11004 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
11005 {
11006 if (!SessionPermission::IsSystemServiceCalling(false)) {
11007 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11008 return WMError::WM_ERROR_INVALID_PERMISSION;
11009 }
11010 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11011 for (const auto& iter: sceneSessionMap_) {
11012 auto& session = iter.second;
11013 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
11014 session->GetSessionInfo().bundleName_ == bundleName) {
11015 session->NotifyCloseExistPipWindow();
11016 break;
11017 }
11018 }
11019 return WMError::WM_OK;
11020 }
11021
GetCurrentPiPWindowInfo(std::string& bundleName)11022 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
11023 {
11024 if (!SessionPermission::IsSystemServiceCalling(false)) {
11025 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11026 return WMError::WM_ERROR_INVALID_PERMISSION;
11027 }
11028 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11029 for (const auto& iter: sceneSessionMap_) {
11030 auto& session = iter.second;
11031 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
11032 bundleName = session->GetSessionInfo().bundleName_;
11033 return WMError::WM_OK;
11034 }
11035 }
11036 TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
11037 return WMError::WM_OK;
11038 }
11039
SkipSnapshotForAppProcess(int32_t pid, bool skip)11040 WMError SceneSessionManager::SkipSnapshotForAppProcess(int32_t pid, bool skip)
11041 {
11042 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11043 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11044 return WMError::WM_ERROR_INVALID_PERMISSION;
11045 }
11046 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d, skip:%{public}u", pid, skip);
11047 auto task = [this, pid, skip]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
11048 if (skip) {
11049 snapshotSkipPidSet_.insert(pid);
11050 } else {
11051 snapshotSkipPidSet_.erase(pid);
11052 }
11053 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11054 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11055 if (sceneSession == nullptr) {
11056 continue;
11057 }
11058 if (pid == sceneSession->GetCallingPid()) {
11059 TLOGI(WmsLogTag::DEFAULT, "send rs set snapshot skip, persistentId:%{public}d, skip:%{public}u",
11060 persistentId, skip);
11061 sceneSession->SetSnapshotSkip(skip);
11062 }
11063 }
11064 };
11065 taskScheduler_->PostTask(task, "SkipSnapshotForAppProcess");
11066 return WMError::WM_OK;
11067 }
11068
RemoveProcessSnapshotSkip(int32_t pid)11069 void SceneSessionManager::RemoveProcessSnapshotSkip(int32_t pid)
11070 {
11071 if (snapshotSkipPidSet_.erase(pid) != 0) {
11072 TLOGI(WmsLogTag::DEFAULT, "process died, delete pid from snapshot skip pid set. pid:%{public}d", pid);
11073 }
11074 }
11075
SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)11076 void SceneSessionManager::SetSessionSnapshotSkipForAppProcess(const sptr<SceneSession>& sceneSession)
11077 {
11078 auto callingPid = sceneSession->GetCallingPid();
11079 if (snapshotSkipPidSet_.find(callingPid) != snapshotSkipPidSet_.end()) {
11080 sceneSession->SetSnapshotSkip(true);
11081 }
11082 }
11083
SkipSnapshotByUserIdAndBundleNames(int32_t userId, const std::vector<std::string>& bundleNameList)11084 WMError SceneSessionManager::SkipSnapshotByUserIdAndBundleNames(int32_t userId,
11085 const std::vector<std::string>& bundleNameList)
11086 {
11087 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11088 TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
11089 return WMError::WM_ERROR_INVALID_PERMISSION;
11090 }
11091 TLOGI(WmsLogTag::DEFAULT, "userId:%{public}d", userId);
11092 auto task = [this, userId, bundleNameList]() THREAD_SAFETY_GUARD(SCENE_GUARD) {
11093 snapshotSkipBundleNameSet_.clear();
11094 for (auto& bundleName : bundleNameList) {
11095 snapshotSkipBundleNameSet_.insert(std::move(bundleName));
11096 }
11097 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11098 for (const auto& [_, sceneSession] : sceneSessionMap_) {
11099 if (sceneSession == nullptr) {
11100 continue;
11101 }
11102 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
11103 if (snapshotSkipBundleNameSet_.find(bundleName) != snapshotSkipBundleNameSet_.end()) {
11104 TLOGNI(WmsLogTag::DEFAULT, "set RS snapshot skip true, name:%{public}s",
11105 bundleName.c_str());
11106 sceneSession->SetSnapshotSkip(true);
11107 continue;
11108 }
11109 sceneSession->SetSnapshotSkip(false);
11110 }
11111 };
11112 taskScheduler_->PostTask(task, __func__);
11113 return WMError::WM_OK;
11114 }
11115
SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)11116 void SceneSessionManager::SetSessionSnapshotSkipForAppBundleName(const sptr<SceneSession>& sceneSession)
11117 {
11118 const std::string& name = sceneSession->GetSessionInfo().bundleName_;
11119 if (snapshotSkipBundleNameSet_.find(name) != snapshotSkipBundleNameSet_.end()) {
11120 TLOGI(WmsLogTag::DEFAULT, "set RS snapshot skip true, name:%{public}s",
11121 name.c_str());
11122 sceneSession->SetSnapshotSkip(true);
11123 }
11124 }
11125
SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)11126 WMError SceneSessionManager::SetProcessWatermark(int32_t pid, const std::string& watermarkName, bool isEnabled)
11127 {
11128 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11129 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11130 return WMError::WM_ERROR_INVALID_PERMISSION;
11131 }
11132 TLOGI(WmsLogTag::DEFAULT, "pid:%{public}d, watermarkName:%{public}s, isEnabled:%{public}u",
11133 pid, watermarkName.c_str(), isEnabled);
11134 if (isEnabled && watermarkName.empty()) {
11135 TLOGE(WmsLogTag::DEFAULT, "watermarkName is empty!");
11136 return WMError::WM_ERROR_INVALID_PARAM;
11137 }
11138 auto task = [this, pid, watermarkName, isEnabled] {
11139 if (isEnabled) {
11140 processWatermarkPidMap_.insert_or_assign(pid, watermarkName);
11141 } else {
11142 processWatermarkPidMap_.erase(pid);
11143 }
11144
11145 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11146 for (const auto& [_, sceneSession] : sceneSessionMap_) {
11147 if (sceneSession == nullptr) {
11148 continue;
11149 }
11150 if (pid == sceneSession->GetCallingPid()) {
11151 sceneSession->SetWatermarkEnabled(watermarkName, isEnabled);
11152 }
11153 }
11154 };
11155 taskScheduler_->PostTask(task, __func__);
11156 return WMError::WM_OK;
11157 }
11158
SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)11159 bool SceneSessionManager::SetSessionWatermarkForAppProcess(const sptr<SceneSession>& sceneSession)
11160 {
11161 if (auto iter = processWatermarkPidMap_.find(sceneSession->GetCallingPid());
11162 iter != processWatermarkPidMap_.end()) {
11163 sceneSession->SetWatermarkEnabled(iter->second, true);
11164 return true;
11165 }
11166 return false;
11167 }
11168
RemoveProcessWatermarkPid(int32_t pid)11169 void SceneSessionManager::RemoveProcessWatermarkPid(int32_t pid)
11170 {
11171 if (processWatermarkPidMap_.find(pid) != processWatermarkPidMap_.end()) {
11172 TLOGI(WmsLogTag::DEFAULT, "process died, delete pid from watermark pid map. pid:%{public}d", pid);
11173 processWatermarkPidMap_.erase(pid);
11174 }
11175 }
11176
GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)11177 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
11178 {
11179 if (!SessionPermission::IsSystemServiceCalling()) {
11180 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11181 return WMError::WM_ERROR_INVALID_PERMISSION;
11182 }
11183 const char* const where = __func__;
11184 auto task = [this, persistentId, &hostWindowId, where]() {
11185 hostWindowId = INVALID_WINDOW_ID;
11186 sptr<Session> session = GetSceneSession(persistentId);
11187 while (session && SessionHelper::IsSubWindow(session->GetWindowType())) {
11188 session = session->GetParentSession();
11189 }
11190 if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
11191 hostWindowId = session->GetPersistentId();
11192 }
11193 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
11194 where, persistentId, hostWindowId);
11195 return WMError::WM_OK;
11196 };
11197 return taskScheduler_->PostSyncTask(task, where);
11198 }
11199
GetMaxInstanceCount(const std::string& bundleName)11200 int32_t SceneSessionManager::GetMaxInstanceCount(const std::string& bundleName)
11201 {
11202 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11203 return MultiInstanceManager::GetInstance().GetMaxInstanceCount(bundleName);
11204 } else {
11205 return 0;
11206 }
11207 }
11208
GetInstanceCount(const std::string& bundleName)11209 int32_t SceneSessionManager::GetInstanceCount(const std::string& bundleName)
11210 {
11211 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11212 return MultiInstanceManager::GetInstance().GetInstanceCount(bundleName);
11213 } else {
11214 return 0;
11215 }
11216 }
11217
GetLastInstanceKey(const std::string& bundleName)11218 std::string SceneSessionManager::GetLastInstanceKey(const std::string& bundleName)
11219 {
11220 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11221 return MultiInstanceManager::GetInstance().GetLastInstanceKey(bundleName);
11222 } else {
11223 return "";
11224 }
11225 }
11226
RefreshAppInfo(const std::string& bundleName)11227 void SceneSessionManager::RefreshAppInfo(const std::string& bundleName)
11228 {
11229 if (MultiInstanceManager::IsSupportMultiInstance(systemConfig_)) {
11230 MultiInstanceManager::GetInstance().RefreshAppInfo(bundleName);
11231 }
11232 }
11233
ReleaseForegroundSessionScreenLock()11234 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
11235 {
11236 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11237 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11238 return WMError::WM_ERROR_INVALID_PERMISSION;
11239 }
11240 #ifdef POWER_MANAGER_ENABLE
11241 auto task = [this] {
11242 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11243 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11244 if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
11245 continue;
11246 }
11247 auto res = sceneSession->keepScreenLock_->UnLock();
11248 if (res != ERR_OK) {
11249 TLOGNE(WmsLogTag::DEFAULT,
11250 "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
11251 persistentId, sceneSession->GetWindowName().c_str(), res);
11252 return WMError::WM_ERROR_INVALID_OPERATION;
11253 }
11254 TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
11255 persistentId, sceneSession->GetWindowName().c_str());
11256 }
11257 return WMError::WM_OK;
11258 };
11259 return taskScheduler_->PostSyncTask(task, __func__);
11260 #else
11261 TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
11262 return WMError::WM_OK;
11263 #endif
11264 }
11265
IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)11266 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
11267 {
11268 isPcOrPadFreeMultiWindowMode = (systemConfig_.IsPcWindow() || systemConfig_.IsFreeMultiWindowMode());
11269 return WMError::WM_OK;
11270 }
11271 } // namespace OHOS::Rosen