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 <regex>
19
20 #include <ability_context.h>
21 #include <ability_manager_client.h>
22 #include <application_context.h>
23 #include <bundlemgr/launcher_service.h>
24 #include <hisysevent.h>
25 #include <parameters.h>
26 #include <hitrace_meter.h>
27 #include "parameter.h"
28 #include "publish/scb_dump_subscriber.h"
29
30 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
31 #include <display_power_mgr_client.h>
32 #endif
33
34 #ifdef POWER_MANAGER_ENABLE
35 #include <power_mgr_client.h>
36 #endif
37
38 #ifdef RES_SCHED_ENABLE
39 #include "res_type.h"
40 #include "res_sched_client.h"
41 #endif
42 #include "scene_system_ability_listener.h"
43
44 #include "anr_manager.h"
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/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 "anr_manager.h"
64 #include "dms_reporter.h"
65 #include "res_sched_client.h"
66 #include "anomaly_detection.h"
67 #include "session/host/include/ability_info_manager.h"
68
69 #ifdef MEMMGR_WINDOW_ENABLE
70 #include "mem_mgr_client.h"
71 #include "mem_mgr_window_info.h"
72 #endif
73
74 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
75 #include "sec_comp_enhance_kit.h"
76 #endif
77
78 #ifdef IMF_ENABLE
79 #include <input_method_controller.h>
80 #endif // IMF_ENABLE
81
82 namespace OHOS::Rosen {
83 namespace {
84 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
85 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
86 const std::string SCENE_BOARD_APP_IDENTIFIER = "";
87 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
88 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
89 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
90
91 constexpr const char* ATOMIC_SERVICE_SESSION_ID = "com.ohos.param.sessionId";
92 constexpr uint32_t MAX_BRIGHTNESS = 255;
93 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
94 constexpr int32_t SCALE_DIMENSION = 2;
95 constexpr int32_t TRANSLATE_DIMENSION = 2;
96 constexpr int32_t ROTAION_DIMENSION = 4;
97 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
98 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
99 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
100 const std::string EMPTY_DEVICE_ID = "";
101 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
102
103 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
104 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
105 constexpr int VALUE_MAX_WIDTH = 5;
106 constexpr int MAX_RESEND_TIMES = 6;
107 constexpr int ORIEN_MAX_WIDTH = 12;
108 constexpr int OFFSET_MAX_WIDTH = 8;
109 constexpr int SCALE_MAX_WIDTH = 8;
110 constexpr int PID_MAX_WIDTH = 8;
111 constexpr int PARENT_ID_MAX_WIDTH = 6;
112 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
113 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
114 const std::string ARG_DUMP_ALL = "-a";
115 const std::string ARG_DUMP_WINDOW = "-w";
116 const std::string ARG_DUMP_SCREEN = "-s";
117 const std::string ARG_DUMP_DISPLAY = "-d";
118 const std::string ARG_DUMP_PIPLINE = "-p";
119 const std::string ARG_DUMP_SCB = "-b";
120 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
121 const int32_t LOGICAL_DISPLACEMENT_32 = 32;
122 constexpr int32_t GET_TOP_WINDOW_DELAY = 100;
123 constexpr uint32_t DEFAULT_LOCK_SCREEN_ZORDER = 2000;
124
125 const std::map<std::string, OHOS::AppExecFwk::DisplayOrientation> STRING_TO_DISPLAY_ORIENTATION_MAP = {
126 {"unspecified", OHOS::AppExecFwk::DisplayOrientation::UNSPECIFIED},
127 {"landscape", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE},
128 {"portrait", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT},
129 {"follow_recent", OHOS::AppExecFwk::DisplayOrientation::FOLLOWRECENT},
130 {"landscape_inverted", OHOS::AppExecFwk::DisplayOrientation::LANDSCAPE_INVERTED},
131 {"portrait_inverted", OHOS::AppExecFwk::DisplayOrientation::PORTRAIT_INVERTED},
132 {"auto_rotation", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION},
133 {"auto_rotation_landscape", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
134 {"auto_rotation_portrait", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT},
135 {"auto_rotation_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_RESTRICTED},
136 {"auto_rotation_landscape_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
137 {"auto_rotation_portrait_restricted", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
138 {"locked", OHOS::AppExecFwk::DisplayOrientation::LOCKED},
139 {"auto_rotation_unspecified", OHOS::AppExecFwk::DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
140 {"follow_desktop", OHOS::AppExecFwk::DisplayOrientation::FOLLOW_DESKTOP},
141 };
142
143 static const std::chrono::milliseconds WAIT_TIME(10 * 1000); // 10 * 1000 wait for 10s
144
145 static std::shared_ptr<ScbDumpSubscriber> g_scbSubscriber(nullptr);
146
GetCurrentTime()147 std::string GetCurrentTime()
148 {
149 struct timespec tn;
150 clock_gettime(CLOCK_REALTIME, &tn);
151 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
152 static_cast<uint64_t>(tn.tv_nsec);
153 return std::to_string(uTime);
154 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)155 int Comp(const std::pair<uint64_t, WindowVisibilityState>& a, const std::pair<uint64_t, WindowVisibilityState>& b)
156 {
157 return a.first < b.first;
158 }
159
GetSingleIntItem(const WindowSceneConfig::ConfigItem & item,int32_t & value)160 bool GetSingleIntItem(const WindowSceneConfig::ConfigItem& item, int32_t& value)
161 {
162 if (item.IsInts() && item.intsValue_ && item.intsValue_->size() == 1) {
163 value = (*item.intsValue_)[0];
164 return true;
165 }
166 return false;
167 }
168
GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo> & abilityInfo)169 bool GetEnableRemoveStartingWindowFromBMS(const std::shared_ptr<AppExecFwk::AbilityInfo>& abilityInfo)
170 {
171 auto& metadata = abilityInfo->metadata;
172 for (const auto& item : metadata) {
173 if (item.name == "enable.remove.starting.window") {
174 return item.value == "true";
175 }
176 }
177 return false;
178 }
179
IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName & element,uint32_t callingTokenId,AppExecFwk::ExtensionAbilityType extensionAbilityType)180 bool IsUIExtCanShowOnLockScreen(const AppExecFwk::ElementName& element, uint32_t callingTokenId,
181 AppExecFwk::ExtensionAbilityType extensionAbilityType)
182 {
183 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: bundleName: %{public}s, moduleName: %{public}s, ablilityName: %{public}s",
184 element.GetBundleName().c_str(), element.GetModuleName().c_str(), element.GetAbilityName().c_str());
185 static const std::unordered_set<AppExecFwk::ExtensionAbilityType> extensionAbilityTypeWhitelist = {
186 AppExecFwk::ExtensionAbilityType::LIVEVIEW_LOCKSCREEN
187 };
188 static const std::vector<std::tuple<std::string, std::string, std::string>> elementNameWhitelist = {
189 std::make_tuple("com.huawei.hmos.settings", "AccessibilityReConfirmDialog", "phone_settings"),
190 std::make_tuple("com.huawei.hmos.settings", "AccessibilityShortKeyDialog", "phone_settings"),
191 std::make_tuple("com.huawei.hmos.settings", "DefaultIntentUiExtensionAbility", "phone_settings"),
192 std::make_tuple("com.ohos.sceneboard", "ScbIntentUIExtensionAbility", "phone_sceneboard"),
193 std::make_tuple("com.ohos.sceneboard", "PoweroffAbility", "phone_sceneboard"),
194 std::make_tuple("com.ohos.sceneboard", "com.ohos.sceneboard.MetaBallsAbility", "metaBallsTurbo"),
195 std::make_tuple("com.huawei.hmos.motiongesture", "IntentUIExtensionAbility", "entry"),
196 std::make_tuple("com.ohos.useriam.authwidget", "userauthuiextensionability", "entry"),
197 std::make_tuple("com.ohos.sceneboard", "AodStyleAbility", "phone_sceneboard"),
198 std::make_tuple("com.ohos.sceneboard", "HomeThemeComponentExtAbility", "themecomponent"),
199 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedResourceAbility", "engineservice"),
200 std::make_tuple("com.ohos.sceneboard", "ThemePersonalizedEditingAbility", "engineservice"),
201 std::make_tuple("com.ohos.sceneboard", "CoverExtensionAbility", "coverthemecomponent"),
202 std::make_tuple("com.huawei.hmos.findservice", "SystemDialogAbility", "entry"),
203 std::make_tuple("com.huawei.hmos.mediacontroller", "UIExtAbility", "phone_deviceswitch"),
204 std::make_tuple("com.huawei.hmos.mediacontroller", "AnahsDialogAbility", "phone_deviceswitch"),
205 std::make_tuple("com.huawei.hmos.security.privacycenter", "SuperPrivacyProtectedAbility", "superprivacy"),
206 std::make_tuple("com.huawei.hmos.security.privacycenter", "PermDisabledReminderAbility", "superprivacy"),
207 std::make_tuple("com.huawei.hmos.audioaccessorymanager", "NearbyAbility", "phone"),
208 std::make_tuple("com.huawei.hmos.wallet", "WalletDialogUIExtensionAbility", "entry"),
209 };
210
211 if (extensionAbilityTypeWhitelist.find(extensionAbilityType) != extensionAbilityTypeWhitelist.end()) {
212 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: extensionAbilityType in white list");
213 return true;
214 }
215
216 auto it = std::find_if(elementNameWhitelist.begin(), elementNameWhitelist.end(), [&element](const auto& item) {
217 auto& [bundleName, abilityName, _] = item;
218 return (element.GetBundleName() == bundleName && element.GetAbilityName() == abilityName);
219 });
220 if (it != elementNameWhitelist.end()) {
221 return true;
222 }
223
224 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in white list");
225 return SessionPermission::VerifyPermissionByCallerToken(callingTokenId,
226 PermissionConstants::PERMISSION_CALLED_EXTENSION_ON_LOCK_SCREEN);
227 }
228
229 class BundleStatusCallback : public IRemoteStub<AppExecFwk::IBundleStatusCallback> {
230 public:
231 BundleStatusCallback() = default;
232 virtual ~BundleStatusCallback() = default;
233
OnBundleStateChanged(const uint8_t installType,const int32_t resultCode,const std::string & resultMsg,const std::string & bundleName)234 void OnBundleStateChanged(const uint8_t installType,
235 const int32_t resultCode, const std::string& resultMsg, const std::string& bundleName) override {}
236
OnBundleAdded(const std::string & bundleName,const int userId)237 void OnBundleAdded(const std::string& bundleName, const int userId) override
238 {
239 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
240 }
241
OnBundleUpdated(const std::string & bundleName,const int userId)242 void OnBundleUpdated(const std::string& bundleName, const int userId) override
243 {
244 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
245 }
246
OnBundleRemoved(const std::string & bundleName,const int userId)247 void OnBundleRemoved(const std::string& bundleName, const int userId) override
248 {
249 SceneSessionManager::GetInstance().OnBundleUpdated(bundleName, userId);
250 }
251 };
252 } // namespace
253
CreateInstance()254 sptr<SceneSessionManager> SceneSessionManager::CreateInstance()
255 {
256 sptr<SceneSessionManager> sessionManager = new SceneSessionManager();
257 sessionManager->Init();
258 return sessionManager;
259 }
260
GetInstance()261 SceneSessionManager& SceneSessionManager::GetInstance()
262 {
263 static sptr<SceneSessionManager> instance = CreateInstance();
264 return *instance;
265 }
266
SceneSessionManager()267 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
268 {
269 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
270 currentUserId_ = DEFAULT_USERID;
271 launcherService_ = new AppExecFwk::LauncherService();
272 if (!launcherService_->RegisterCallback(new BundleStatusCallback())) {
273 WLOGFE("Failed to register bundle status callback.");
274 }
275 ScbDumpSubscriber::Subscribe(g_scbSubscriber);
276 }
277
~SceneSessionManager()278 SceneSessionManager::~SceneSessionManager()
279 {
280 ScbDumpSubscriber::UnSubscribe(g_scbSubscriber);
281 }
282
Init()283 void SceneSessionManager::Init()
284 {
285 auto deviceType = system::GetParameter("const.product.devicetype", "unknown");
286 bool isScbCoreEnabled = (deviceType == UI_TYPE_PHONE || deviceType == "tablet") &&
287 system::GetParameter("persist.window.scbcore.enable", "1") == "1";
288 Session::SetScbCoreEnabled(isScbCoreEnabled);
289
290 constexpr uint64_t interval = 5 * 1000; // 5 second
291 if (HiviewDFX::Watchdog::GetInstance().AddThread(
292 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
293 WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
294 }
295
296 bundleMgr_ = GetBundleManager();
297 LoadWindowSceneXml();
298 sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
299 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
300 InitPrepareTerminateConfig();
301 // create handler for inner command at server
302 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
303 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
304 if (eventHandler_ == nullptr) {
305 WLOGFE("Invalid eventHander");
306 return ;
307 }
308 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
309 if (ret != 0) {
310 WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
311 }
312
313 listenerController_ = std::make_shared<SessionListenerController>();
314 listenerController_->Init();
315 scbSessionHandler_ = new ScbSessionHandler();
316 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
317 StartWindowInfoReportLoop();
318 WLOGI("SSM init success.");
319 RegisterAppListener();
320 openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
321 isKeyboardPanelEnabled_ = system::GetParameter("persist.sceneboard.keyboardPanel.enabled", "1") == "1";
322 SceneInputManager::GetInstance().Init();
323
324 // MMI window state error check
325 int32_t retCode = MMI::InputManager::GetInstance()->
326 RegisterWindowStateErrorCallback([this](int32_t pid, int32_t persistentId) {
327 this->NotifyWindowStateErrorFromMMI(pid, persistentId);
328 });
329 TLOGI(WmsLogTag::WMS_EVENT, "register WindowStateError callback with ret: %{public}d", retCode);
330
331 AbilityInfoManager::GetInstance().Init(bundleMgr_);
332 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
333 UpdateDarkColorModeToRS();
334 }
335
InitScheduleUtils()336 void SceneSessionManager::InitScheduleUtils()
337 {
338 #ifdef RES_SCHED_ENABLE
339 SCBThreadInfo threadInfo = {
340 .scbUid_ = std::to_string(getuid()), .scbPid_ = std::to_string(getprocpid()),
341 .scbTid_ = std::to_string(getproctid()), .scbBundleName_ = SCENE_BOARD_BUNDLE_NAME
342 };
343 std::unordered_map<std::string, std::string> payload {
344 { "pid", threadInfo.scbPid_ },
345 { "tid", threadInfo.scbTid_ },
346 { "uid", threadInfo.scbUid_ },
347 { "bundleName", threadInfo.scbBundleName_ },
348 };
349 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
350 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
351 auto task = [threadInfo = std::move(threadInfo)]() mutable {
352 threadInfo.ssmThreadName_ = "OS_SceneSession";
353 threadInfo.ssmTid_ = std::to_string(gettid());
354 const int32_t userInteraction = 2;
355 std::unordered_map<std::string, std::string> payload{
356 { "pid", threadInfo.scbPid_ },
357 { "tid", threadInfo.ssmTid_ },
358 { "uid", threadInfo.scbUid_ },
359 { "extType", "10002" },
360 { "cgroupPrio", "1" },
361 { "isSa", "0" },
362 { "threadName", threadInfo.ssmThreadName_ }
363 };
364 uint32_t type = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
365 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, userInteraction, payload);
366 TLOGI(WmsLogTag::WMS_LIFE, "set RES_TYPE_KEY_PERF_SCENE success");
367 sptr<ISystemAbilityManager> systemAbilityManager =
368 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
369 if (!systemAbilityManager) {
370 TLOGE(WmsLogTag::WMS_MAIN, "failed to get system ability manager client");
371 return;
372 }
373 auto statusChangeListener = sptr<SceneSystemAbilityListener>::MakeSptr(threadInfo);
374 int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, statusChangeListener);
375 if (ret != ERR_OK) {
376 TLOGI(WmsLogTag::WMS_MAIN, "failed to subscribe system ability manager");
377 }
378 };
379 taskScheduler_->PostAsyncTask(task, "changeQosTask");
380 #endif
381 }
382
RegisterAppListener()383 void SceneSessionManager::RegisterAppListener()
384 {
385 appAnrListener_ = new (std::nothrow) AppAnrListener();
386 auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
387 if (appMgrClient_ == nullptr) {
388 WLOGFE("appMgrClient_ is nullptr.");
389 } else if (appAnrListener_ == nullptr) {
390 WLOGFE("appAnrListener_ is nullptr.");
391 } else {
392 auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
393 if (flag != ERR_OK) {
394 WLOGFE("Register app debug listener failed.");
395 } else {
396 WLOGFI("Register app debug listener success.");
397 }
398 }
399 }
400
LoadWindowSceneXml()401 void SceneSessionManager::LoadWindowSceneXml()
402 {
403 if (WindowSceneConfig::LoadConfigXml()) {
404 if (WindowSceneConfig::GetConfig().IsMap()) {
405 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
406 }
407 ConfigWindowSceneXml();
408 } else {
409 WLOGFE("Load window scene xml failed");
410 }
411 ConfigDefaultKeyboardAnimation(appWindowSceneConfig_.keyboardAnimationIn_,
412 appWindowSceneConfig_.keyboardAnimationOut_);
413 }
414
InitPrepareTerminateConfig()415 void SceneSessionManager::InitPrepareTerminateConfig()
416 {
417 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
418 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
419 PREPARE_TERMINATE_ENABLE_SIZE);
420 WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
421 if (retSysParam > 0 && !std::strcmp(value, "true")) {
422 isPrepareTerminateEnable_ = true;
423 }
424 }
425
ConfigWindowSceneXml()426 void SceneSessionManager::ConfigWindowSceneXml()
427 {
428 const auto& config = WindowSceneConfig::GetConfig();
429 WindowSceneConfig::ConfigItem item = config["windowEffect"];
430 if (item.IsMap()) {
431 ConfigWindowEffect(item);
432 }
433
434 item = config["decor"];
435 if (item.IsMap()) {
436 ConfigDecor(item);
437 }
438
439 item = config["backgroundswitch"];
440 if (item.IsInts()) {
441 auto numbers = *item.intsValue_;
442 if (numbers.size() == 1 && numbers[0] == 1) {
443 systemConfig_.backgroundswitch = true;
444 }
445 }
446 WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
447
448 item = config["defaultWindowMode"];
449 if (item.IsInts()) {
450 auto numbers = *item.intsValue_;
451 if (numbers.size() == 1 &&
452 (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
453 numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
454 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
455 }
456 }
457
458 item = config["defaultMaximizeMode"];
459 if (item.IsInts()) {
460 auto numbers = *item.intsValue_;
461 if (numbers.size() == 1 &&
462 (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
463 numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
464 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
465 }
466 }
467
468 item = config["keyboardAnimation"];
469 if (item.IsMap()) {
470 ConfigKeyboardAnimation(item);
471 }
472
473 item = config["maxFloatingWindowSize"];
474 if (item.IsInts()) {
475 auto numbers = *item.intsValue_;
476 if (numbers.size() == 1) {
477 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
478 }
479 }
480
481 item = config["windowAnimation"];
482 if (item.IsMap()) {
483 ConfigWindowAnimation(item);
484 }
485
486 item = config["startWindowTransitionAnimation"];
487 if (item.IsMap()) {
488 ConfigStartingWindowAnimation(item);
489 }
490 item = config["maxMidSceneNum"];
491 if (item.IsInts()) {
492 auto numbers = *item.intsValue_;
493 if (numbers.size() == 1) {
494 systemConfig_.maxMidSceneNum_ = static_cast<uint32_t>(numbers[0]);
495 }
496 }
497 ConfigFreeMultiWindow();
498 ConfigWindowSizeLimits();
499 ConfigSnapshotScale();
500 ConfigWindowSceneXml(config);
501 }
502
ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem & config)503 void SceneSessionManager::ConfigWindowSceneXml(const WindowSceneConfig::ConfigItem& config)
504 {
505 WindowSceneConfig::ConfigItem item = config["systemUIStatusBar"];
506 if (item.IsMap()) {
507 ConfigSystemUIStatusBar(item);
508 }
509 item = config["uiType"];
510 if (item.IsString()) {
511 systemConfig_.uiType_ = item.stringValue_;
512 appWindowSceneConfig_.uiType_ = item.stringValue_;
513 }
514 item = config["backgroundScreenLock"].GetProp("enable");
515 if (item.IsBool()) {
516 appWindowSceneConfig_.backgroundScreenLock_ = item.boolValue_;
517 }
518 item = config["rotationMode"];
519 if (item.IsString()) {
520 appWindowSceneConfig_.rotationMode_ = item.stringValue_;
521 }
522 item = config["immersive"];
523 if (item.IsMap()) {
524 ConfigWindowImmersive(item);
525 }
526 item = config["supportTypeFloatWindow"].GetProp("enable");
527 if (item.IsBool()) {
528 systemConfig_.supportTypeFloatWindow_ = item.boolValue_;
529 }
530 }
531
ConfigWindowImmersive(const WindowSceneConfig::ConfigItem & immersiveConfig)532 void SceneSessionManager::ConfigWindowImmersive(const WindowSceneConfig::ConfigItem& immersiveConfig)
533 {
534 AppWindowSceneConfig config;
535 WindowSceneConfig::ConfigItem item = immersiveConfig["inDesktopStatusBarConfig"];
536 if (item.IsMap()) {
537 if (ConfigStatusBar(item, config.windowImmersive_.desktopStatusBarConfig_)) {
538 appWindowSceneConfig_.windowImmersive_.desktopStatusBarConfig_ =
539 config.windowImmersive_.desktopStatusBarConfig_;
540 }
541 }
542 item = immersiveConfig["inSplitStatusBarConfig"]["upDownSplit"];
543 if (item.IsMap()) {
544 if (ConfigStatusBar(item, config.windowImmersive_.upDownStatusBarConfig_)) {
545 appWindowSceneConfig_.windowImmersive_.upDownStatusBarConfig_ =
546 config.windowImmersive_.upDownStatusBarConfig_;
547 }
548 }
549 item = immersiveConfig["inSplitStatusBarConfig"]["leftRightSplit"];
550 if (item.IsMap()) {
551 if (ConfigStatusBar(item, config.windowImmersive_.leftRightStatusBarConfig_)) {
552 appWindowSceneConfig_.windowImmersive_.leftRightStatusBarConfig_ =
553 config.windowImmersive_.leftRightStatusBarConfig_;
554 }
555 }
556 }
557
ConfigStatusBar(const WindowSceneConfig::ConfigItem & config,StatusBarConfig & statusBarConfig)558 bool SceneSessionManager::ConfigStatusBar(const WindowSceneConfig::ConfigItem& config,
559 StatusBarConfig& statusBarConfig)
560 {
561 WindowSceneConfig::ConfigItem item = config["showHide"].GetProp("enable");
562 if (item.IsBool()) {
563 statusBarConfig.showHide_ = item.boolValue_;
564 }
565 item = config["contentColor"];
566 if (item.IsString()) {
567 statusBarConfig.contentColor_ = item.stringValue_;
568 }
569 item = config["backgroundColor"];
570 if (item.IsString()) {
571 statusBarConfig.backgroundColor_ = item.stringValue_;
572 }
573 return true;
574 }
575
ConfigFreeMultiWindow()576 void SceneSessionManager::ConfigFreeMultiWindow()
577 {
578 const auto& config = WindowSceneConfig::GetConfig();
579 WindowSceneConfig::ConfigItem freeMultiWindowConfig = config["freeMultiWindow"];
580 if (freeMultiWindowConfig.IsMap()) {
581 auto supportItem = freeMultiWindowConfig.GetProp("enable");
582 if (supportItem.IsBool()) {
583 systemConfig_.freeMultiWindowSupport_ = supportItem.boolValue_;
584 }
585 auto item = freeMultiWindowConfig["decor"];
586 if (item.IsMap()) {
587 ConfigDecor(item, false);
588 }
589 int32_t param = -1;
590 item = freeMultiWindowConfig["defaultWindowMode"];
591 if (GetSingleIntItem(item, param) &&
592 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
593 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
594 systemConfig_.freeMultiWindowConfig_.defaultWindowMode_ =
595 static_cast<WindowMode>(static_cast<uint32_t>(param));
596 }
597 item = freeMultiWindowConfig["maxMainFloatingWindowNumber"];
598 if (GetSingleIntItem(item, param) && (param > 0)) {
599 systemConfig_.freeMultiWindowConfig_.maxMainFloatingWindowNumber_ = static_cast<uint32_t>(param);
600 }
601 }
602 }
603
LoadFreeMultiWindowConfig(bool enable)604 void SceneSessionManager::LoadFreeMultiWindowConfig(bool enable)
605 {
606 FreeMultiWindowConfig freeMultiWindowConfig = systemConfig_.freeMultiWindowConfig_;
607 if (enable) {
608 systemConfig_.defaultWindowMode_ = freeMultiWindowConfig.defaultWindowMode_;
609 systemConfig_.decorWindowModeSupportType_ = freeMultiWindowConfig.decorWindowModeSupportType_;
610 systemConfig_.isSystemDecorEnable_ = freeMultiWindowConfig.isSystemDecorEnable_;
611 } else {
612 const auto& config = WindowSceneConfig::GetConfig();
613 auto item = config["decor"];
614 if (item.IsMap()) {
615 ConfigDecor(item, true);
616 }
617 int32_t param = -1;
618 item = config["defaultWindowMode"];
619 if (GetSingleIntItem(item, param) &&
620 (param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
621 param == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
622 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(param));
623 }
624 }
625 systemConfig_.freeMultiWindowEnable_ = enable;
626 }
627
GetSystemSessionConfig() const628 const SystemSessionConfig& SceneSessionManager::GetSystemSessionConfig() const
629 {
630 return systemConfig_;
631 }
632
SwitchFreeMultiWindow(bool enable)633 WSError SceneSessionManager::SwitchFreeMultiWindow(bool enable)
634 {
635 if (!systemConfig_.freeMultiWindowSupport_) {
636 TLOGE(WmsLogTag::WMS_LAYOUT, "device not support");
637 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
638 }
639 LoadFreeMultiWindowConfig(enable);
640 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
641 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
642 auto sceneSession = item->second;
643 if (sceneSession == nullptr) {
644 continue;
645 }
646 auto property = sceneSession->GetSessionProperty();
647 if (property == nullptr) {
648 continue;
649 }
650 bool isUiExtSubWindow = WindowHelper::IsSubWindow(property->GetWindowType()) &&
651 property->GetExtensionFlag();
652 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType()) || isUiExtSubWindow) {
653 sceneSession->SwitchFreeMultiWindow(enable);
654 }
655 }
656 WindowStyleType type = enable ?
657 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
658 SessionManagerAgentController::GetInstance().NotifyWindowStyleChange(type);
659 return WSError::WS_OK;
660 }
661
GetFreeMultiWindowEnableState(bool & enable)662 WSError SceneSessionManager::GetFreeMultiWindowEnableState(bool& enable)
663 {
664 enable = systemConfig_.freeMultiWindowEnable_;
665 return WSError::WS_OK;
666 }
667
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)668 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
669 const ContinueState& continueState)
670 {
671 TLOGI(WmsLogTag::DEFAULT, "Enter");
672 auto task = [this, token, continueState]() {
673 sptr <SceneSession> sceneSession = FindSessionByToken(token);
674 if (sceneSession == nullptr) {
675 TLOGE(WmsLogTag::DEFAULT, "fail to find session by token.");
676 return WSError::WS_ERROR_INVALID_PARAM;
677 }
678 sceneSession->SetSessionInfoContinueState(continueState);
679 DistributedClient::GetInstance().SetMissionContinueState(sceneSession->GetPersistentId(),
680 static_cast<AAFwk::ContinueState>(continueState));
681 TLOGI(WmsLogTag::DEFAULT, "SetSessionContinueState id:%{public}d, continueState:%{public}d",
682 sceneSession->GetPersistentId(), continueState);
683 return WSError::WS_OK;
684 };
685 return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
686 }
687
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig,bool mainConfig)688 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig, bool mainConfig)
689 {
690 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
691 if (item.IsBool()) {
692 if (mainConfig) {
693 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
694 } else {
695 systemConfig_.freeMultiWindowConfig_.isSystemDecorEnable_ = item.boolValue_;
696 }
697 bool decorEnable = item.boolValue_;
698 uint32_t support = 0;
699 std::vector<std::string> supportedModes;
700 item = decorConfig["supportedMode"];
701 if (item.IsStrings()) {
702 supportedModes = *item.stringsValue_;
703 }
704 for (auto mode : supportedModes) {
705 if (mode == "fullscreen") {
706 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
707 } else if (mode == "floating") {
708 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
709 } else if (mode == "pip") {
710 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
711 } else if (mode == "split") {
712 support |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
713 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
714 } else {
715 WLOGFW("Invalid supporedMode");
716 support = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
717 break;
718 }
719 }
720 if (mainConfig && item.IsStrings()) {
721 systemConfig_.decorWindowModeSupportType_ = support;
722 }
723 if (!mainConfig && item.IsStrings()) {
724 systemConfig_.freeMultiWindowConfig_.decorWindowModeSupportType_ = support;
725 }
726 }
727 }
728
AddAlphaToColor(float alpha,std::string & color)729 static void AddAlphaToColor(float alpha, std::string& color)
730 {
731 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
732 return;
733 }
734
735 uint32_t alphaValue = 0xFF * alpha;
736 std::stringstream ss;
737 ss << std::hex << alphaValue;
738 std::string strAlpha = ss.str();
739 if (strAlpha.size() == 1) {
740 strAlpha.append(1, '0');
741 }
742
743 color.insert(1, strAlpha);
744 }
745
IsAtomicServiceFreeInstall(const SessionInfo & sessionInfo)746 static inline bool IsAtomicServiceFreeInstall(const SessionInfo& sessionInfo)
747 {
748 return sessionInfo.isAtomicService_ && sessionInfo.want != nullptr &&
749 (sessionInfo.want->GetFlags() & AAFwk::Want::FLAG_INSTALL_ON_DEMAND) ==
750 AAFwk::Want::FLAG_INSTALL_ON_DEMAND;
751 }
752
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)753 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
754 {
755 AppWindowSceneConfig config;
756 // config corner radius
757 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
758 if (item.IsMap()) {
759 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
760 appWindowSceneConfig_ = config;
761 }
762 }
763
764 // config shadow
765 item = effectConfig["appWindows"]["shadow"]["focused"];
766 if (item.IsMap()) {
767 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
768 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
769 }
770 }
771
772 item = effectConfig["appWindows"]["shadow"]["unfocused"];
773 if (item.IsMap()) {
774 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
775 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
776 }
777 }
778
779 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
780 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
781
782 WLOGFI("Config window effect successfully");
783 }
784
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)785 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
786 {
787 std::map<std::string, float> stringToCornerRadius = {
788 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
789 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
790 };
791
792 if (item.IsString()) {
793 auto value = item.stringValue_;
794 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
795 out = stringToCornerRadius[value];
796 return true;
797 }
798 }
799 return false;
800 }
801
SetEnableInputEvent(bool enabled)802 void SceneSessionManager::SetEnableInputEvent(bool enabled)
803 {
804 TLOGI(WmsLogTag::WMS_RECOVER, "enabled: %{public}u", enabled);
805 enableInputEvent_ = enabled;
806 }
807
IsInputEventEnabled()808 bool SceneSessionManager::IsInputEventEnabled()
809 {
810 return enableInputEvent_;
811 }
812
ClearUnrecoveredSessions(const std::vector<int32_t> & recoveredPersistentIds)813 void SceneSessionManager::ClearUnrecoveredSessions(const std::vector<int32_t>& recoveredPersistentIds)
814 {
815 for (const auto& persistentId : alivePersistentIds_) {
816 auto it = std::find(recoveredPersistentIds.begin(), recoveredPersistentIds.end(), persistentId);
817 if (it != recoveredPersistentIds.end()) {
818 continue;
819 }
820 auto sceneSession = GetSceneSession(persistentId);
821 if (sceneSession == nullptr) {
822 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
823 continue;
824 }
825 if (sceneSession->IsRecovered()) {
826 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId=%{public}d", persistentId);
827 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
828 EraseSceneSessionAndMarkDirtyLocked(persistentId);
829 }
830 }
831 }
832
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)833 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
834 {
835 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds recovered = %{public}zu. CurrentUserId = %{public}d",
836 recoveredPersistentIds.size(), currentUserId_.load());
837
838 auto task = [this, recoveredPersistentIds]() {
839 ClearUnrecoveredSessions(recoveredPersistentIds);
840 std::list<AAFwk::SessionInfo> abilitySessionInfos;
841 for (const auto& persistentId : recoveredPersistentIds) {
842 if (failRecoveredPersistentIdSet_.count(persistentId)) {
843 TLOGI(WmsLogTag::WMS_RECOVER, "failRecoveredPersistentId = %{public}d, continue", persistentId);
844 continue;
845 }
846 auto sceneSession = GetSceneSession(persistentId);
847 if (sceneSession == nullptr) {
848 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
849 continue;
850 }
851 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
852 if (!abilitySessionInfo) {
853 TLOGW(WmsLogTag::WMS_RECOVER, "abilitySessionInfo is null, persistentId = %{public}d", persistentId);
854 continue;
855 }
856 TLOGD(WmsLogTag::WMS_RECOVER, "recovered persistentId = %{public}d", persistentId);
857 abilitySessionInfos.emplace_back(*abilitySessionInfo);
858 }
859 std::vector<int32_t> unrecoverableSessionIds;
860 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
861 abilitySessionInfos, currentUserId_, unrecoverableSessionIds);
862 TLOGI(WmsLogTag::WMS_RECOVER, "Number of unrecoverableSessionIds = %{public}zu",
863 unrecoverableSessionIds.size());
864 for (const auto& sessionId : unrecoverableSessionIds) {
865 auto sceneSession = GetSceneSession(sessionId);
866 if (sceneSession == nullptr) {
867 TLOGW(WmsLogTag::WMS_RECOVER, "There is no session corresponding to persistentId = %{public}d ",
868 sessionId);
869 continue;
870 }
871 const auto& scnSessionInfo = SetAbilitySessionInfo(sceneSession);
872 if (!scnSessionInfo) {
873 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is null, persistentId = %{public}d", sessionId);
874 continue;
875 }
876 TLOGI(WmsLogTag::WMS_RECOVER, "unrecoverable persistentId = %{public}d", sessionId);
877 sceneSession->NotifySessionExceptionInner(scnSessionInfo, false);
878 }
879 removeFailRecoveredSession();
880 };
881 return taskScheduler_->PostAsyncTask(task);
882 }
883
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)884 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
885 WindowShadowConfig& outShadow)
886 {
887 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
888 if (item.IsString()) {
889 auto color = item.stringValue_;
890 uint32_t colorValue;
891 if (!ColorParser::Parse(color, colorValue)) {
892 return false;
893 }
894 outShadow.color_ = color;
895 }
896
897 item = shadowConfig["offsetX"];
898 if (item.IsFloats()) {
899 auto offsetX = *item.floatsValue_;
900 if (offsetX.size() != 1) {
901 return false;
902 }
903 outShadow.offsetX_ = offsetX[0];
904 }
905
906 item = shadowConfig["offsetY"];
907 if (item.IsFloats()) {
908 auto offsetY = *item.floatsValue_;
909 if (offsetY.size() != 1) {
910 return false;
911 }
912 outShadow.offsetY_ = offsetY[0];
913 }
914
915 item = shadowConfig["alpha"];
916 if (item.IsFloats()) {
917 auto alpha = *item.floatsValue_;
918 if (alpha.size() != 1 ||
919 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
920 return false;
921 }
922 outShadow.alpha_ = alpha[0];
923 }
924
925 item = shadowConfig["radius"];
926 if (item.IsFloats()) {
927 auto radius = *item.floatsValue_;
928 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
929 return false;
930 }
931 outShadow.radius_ = radius[0];
932 }
933
934 return true;
935 }
936
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)937 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
938 KeyboardSceneAnimationConfig& config)
939 {
940 if (item.IsMap() && item.mapValue_->count("curve")) {
941 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
942 config.curveType_ = curveType;
943 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
944 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
945 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
946 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
947 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
948 }
949 }
950
951 const WindowSceneConfig::ConfigItem& duration = item["duration"];
952 if (duration.IsInts()) {
953 auto numbers = *duration.intsValue_;
954 if (numbers.size() == 1) {
955 config.duration_ = static_cast<uint32_t>(numbers[0]);
956 }
957 }
958 }
959
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)960 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
961 {
962 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
963 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
964
965 // config system animation
966 const auto& appConfigIn = appWindowSceneConfig_.keyboardAnimationIn_;
967 systemConfig_.animationIn_ = KeyboardAnimationCurve(appConfigIn.curveType_,
968 {appConfigIn.ctrlX1_, appConfigIn.ctrlY1_, appConfigIn.ctrlX2_, appConfigIn.ctrlY2_},
969 appConfigIn.duration_);
970 const auto& appConfigOut = appWindowSceneConfig_.keyboardAnimationOut_;
971 systemConfig_.animationOut_ = KeyboardAnimationCurve(appConfigOut.curveType_,
972 {appConfigOut.ctrlX1_, appConfigOut.ctrlY1_, appConfigOut.ctrlX2_, appConfigOut.ctrlY2_},
973 appConfigOut.duration_);
974 }
975
ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig & animationIn,KeyboardSceneAnimationConfig & animationOut)976 void SceneSessionManager::ConfigDefaultKeyboardAnimation(KeyboardSceneAnimationConfig& animationIn,
977 KeyboardSceneAnimationConfig& animationOut)
978 {
979 if (!(systemConfig_.animationIn_.curveType_.empty() && systemConfig_.animationOut_.curveType_.empty())) {
980 TLOGI(WmsLogTag::WMS_KEYBOARD, "product config, curveIn:[%{public}s, %{public}u], "
981 "curveOut:[%{public}s, %{public}u]", systemConfig_.animationIn_.curveType_.c_str(),
982 systemConfig_.animationIn_.duration_, systemConfig_.animationOut_.curveType_.c_str(),
983 systemConfig_.animationOut_.duration_);
984 return;
985 }
986
987 // default animation curve params
988 constexpr char CURVETYPE[] = "interpolatingSpring";
989 constexpr float IN_CTRLX1 = 0.0f;
990 constexpr float OUT_CTRLX1 = 4.0f;
991 constexpr float CTRLY1 = 1.0f;
992 constexpr float CTRLX2 = 342.0f;
993 constexpr float CTRLY2 = 37.0f;
994 constexpr uint32_t DURATION = 150;
995 std::vector<float> in = { IN_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
996 std::vector<float> out = { OUT_CTRLX1, CTRLY1, CTRLX2, CTRLY2 };
997
998 // update system config for client
999 systemConfig_.animationIn_ = KeyboardAnimationCurve(CURVETYPE, in, DURATION);
1000 systemConfig_.animationOut_ = KeyboardAnimationCurve(CURVETYPE, out, DURATION);
1001
1002 // update app config for server
1003 animationIn.curveType_ = CURVETYPE;
1004 animationIn.ctrlX1_ = in[0]; // 0: ctrl x1 index
1005 animationIn.ctrlY1_ = in[1]; // 1: ctrl y1 index
1006 animationIn.ctrlX2_ = in[2]; // 2: ctrl x2 index
1007 animationIn.ctrlY2_ = in[3]; // 3: ctrl y2 index
1008 animationIn.duration_ = DURATION;
1009
1010 animationOut.curveType_ = CURVETYPE;
1011 animationOut.ctrlX1_ = out[0]; // 0: ctrl x1 index
1012 animationOut.ctrlY1_ = out[1]; // 1: ctrl y1 index
1013 animationOut.ctrlX2_ = out[2]; // 2: ctrl x2 index
1014 animationOut.ctrlY2_ = out[3]; // 3: ctrl y2 index
1015 animationOut.duration_ = DURATION;
1016 TLOGI(WmsLogTag::WMS_KEYBOARD, "use default config");
1017 }
1018
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)1019 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
1020 {
1021 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
1022 if (item.IsMap() && item.mapValue_->count("curve")) {
1023 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
1024 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
1025 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
1026 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
1027 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
1028 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
1029 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
1030 }
1031 }
1032 item = windowAnimationConfig["timing"]["duration"];
1033 if (item.IsInts() && item.intsValue_->size() == 1) {
1034 auto duration = *item.intsValue_;
1035 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
1036 }
1037 item = windowAnimationConfig["scale"];
1038 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
1039 auto scales = *item.floatsValue_;
1040 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
1041 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
1042 }
1043 item = windowAnimationConfig["rotation"];
1044 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
1045 auto rotations = *item.floatsValue_;
1046 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
1047 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
1048 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
1049 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
1050 }
1051 item = windowAnimationConfig["translate"];
1052 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
1053 auto translates = *item.floatsValue_;
1054 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
1055 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
1056 }
1057 item = windowAnimationConfig["opacity"];
1058 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1059 auto opacity = *item.floatsValue_;
1060 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
1061 }
1062 }
1063
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)1064 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
1065 {
1066 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
1067 auto item = configItem.GetProp("enable");
1068 if (item.IsBool()) {
1069 config.enabled_ = item.boolValue_;
1070 }
1071 item = configItem["timing"];
1072 if (item.IsMap() && item.mapValue_->count("curve")) {
1073 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
1074 }
1075 item = configItem["timing"]["duration"];
1076 if (item.IsInts() && item.intsValue_->size() == 1) {
1077 config.duration_ = (*item.intsValue_)[0];
1078 }
1079 item = configItem["opacityStart"];
1080 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1081 config.opacityStart_ = (*item.floatsValue_)[0];
1082 }
1083 item = configItem["opacityEnd"];
1084 if (item.IsFloats() && item.floatsValue_->size() == 1) {
1085 config.opacityEnd_ = (*item.floatsValue_)[0];
1086 }
1087 }
1088
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)1089 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
1090 const WindowSceneConfig::ConfigItem& curveConfig)
1091 {
1092 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
1093 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
1094 static std::unordered_set<std::string> paramCurveSet = {
1095 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
1096
1097 std::string curveName = "easeOut";
1098 const auto& nameItem = curveConfig.GetProp("name");
1099 if (!nameItem.IsString()) {
1100 return {curveName, {}};
1101 }
1102
1103 std::string name = nameItem.stringValue_;
1104 std::vector<float> curveParams;
1105
1106 if (paramCurveSet.find(name) != paramCurveSet.end()) {
1107 curveName = name;
1108 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
1109 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
1110 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
1111 curveParams.begin());
1112 }
1113 } else {
1114 auto iter = curveSet.find(name);
1115 if (iter != curveSet.end()) {
1116 curveName = name;
1117 }
1118 }
1119
1120 return {curveName, curveParams};
1121 }
1122
ConfigWindowSizeLimits()1123 void SceneSessionManager::ConfigWindowSizeLimits()
1124 {
1125 const auto& config = WindowSceneConfig::GetConfig();
1126 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
1127 if (item.IsMap()) {
1128 ConfigMainWindowSizeLimits(item);
1129 }
1130
1131 item = config["subWindowSizeLimits"];
1132 if (item.IsMap()) {
1133 ConfigSubWindowSizeLimits(item);
1134 }
1135 }
1136
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)1137 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
1138 {
1139 auto item = mainWindowSizeConifg["miniWidth"];
1140 if (item.IsInts()) {
1141 auto numbers = *item.intsValue_;
1142 if (numbers.size() == 1) {
1143 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1144 }
1145 }
1146
1147 item = mainWindowSizeConifg["miniHeight"];
1148 if (item.IsInts()) {
1149 auto numbers = *item.intsValue_;
1150 if (numbers.size() == 1) {
1151 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
1152 }
1153 }
1154 }
1155
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)1156 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
1157 {
1158 auto item = subWindowSizeConifg["miniWidth"];
1159 if (item.IsInts()) {
1160 auto numbers = *item.intsValue_;
1161 if (numbers.size() == 1) {
1162 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1163 }
1164 }
1165
1166 item = subWindowSizeConifg["miniHeight"];
1167 if (item.IsInts()) {
1168 auto numbers = *item.intsValue_;
1169 if (numbers.size() == 1) {
1170 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
1171 }
1172 }
1173 }
1174
ConfigSnapshotScale()1175 void SceneSessionManager::ConfigSnapshotScale()
1176 {
1177 const auto& config = WindowSceneConfig::GetConfig();
1178 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
1179 if (item.IsFloats()) {
1180 auto snapshotScale = *item.floatsValue_;
1181 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
1182 return;
1183 }
1184 snapshotScale_ = snapshotScale[0];
1185 }
1186 }
1187
ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem & statusBarConfig)1188 void SceneSessionManager::ConfigSystemUIStatusBar(const WindowSceneConfig::ConfigItem& statusBarConfig)
1189 {
1190 TLOGI(WmsLogTag::WMS_IMMS, "load ConfigSystemUIStatusBar");
1191 WindowSceneConfig::ConfigItem item = statusBarConfig["showInLandscapeMode"];
1192 if (item.IsInts() && item.intsValue_->size() == 1) {
1193 bool showInLandscapeMode = (*item.intsValue_)[0] > 0;
1194 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_ = showInLandscapeMode;
1195 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar showInLandscapeMode:%{public}d",
1196 appWindowSceneConfig_.systemUIStatusBarConfig_.showInLandscapeMode_);
1197 }
1198
1199 item = statusBarConfig["immersiveStatusBarBgColor"];
1200 if (item.IsString()) {
1201 auto color = item.stringValue_;
1202 uint32_t colorValue;
1203 if (!ColorParser::Parse(color, colorValue)) {
1204 return;
1205 }
1206 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_ = color;
1207 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarBgColor:%{public}s",
1208 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarBgColor_.c_str());
1209 }
1210
1211 item = statusBarConfig["immersiveStatusBarContentColor"];
1212 if (item.IsString()) {
1213 auto color = item.stringValue_;
1214 uint32_t colorValue;
1215 if (!ColorParser::Parse(color, colorValue)) {
1216 return;
1217 }
1218 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_ = color;
1219 TLOGI(WmsLogTag::WMS_IMMS, "ConfigSystemUIStatusBar immersiveStatusBarContentColor:%{public}s",
1220 appWindowSceneConfig_.systemUIStatusBarConfig_.immersiveStatusBarContentColor_.c_str());
1221 }
1222 }
1223
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)1224 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
1225 {
1226 rootSceneContextWeak_ = contextWeak;
1227 }
1228
GetRootSceneSession()1229 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
1230 {
1231 auto task = [this]() -> sptr<RootSceneSession> {
1232 if (rootSceneSession_ != nullptr) {
1233 return rootSceneSession_;
1234 }
1235 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
1236 rootSceneSession_ = new RootSceneSession();
1237 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
1238 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
1239 return rootSceneSession_;
1240 };
1241
1242 return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
1243 }
1244
GetRootSessionAvoidSessionRect(AvoidAreaType type)1245 WSRect SceneSessionManager::GetRootSessionAvoidSessionRect(AvoidAreaType type)
1246 {
1247 sptr<RootSceneSession> rootSession = GetRootSceneSession();
1248 if (rootSession == nullptr || rootSession->GetSessionProperty() == nullptr) {
1249 return {};
1250 }
1251 DisplayId displayId = rootSession->GetSessionProperty()->GetDisplayId();
1252 std::vector<sptr<SceneSession>> sessionVector;
1253 switch (type) {
1254 case AvoidAreaType::TYPE_SYSTEM: {
1255 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
1256 break;
1257 }
1258 case AvoidAreaType::TYPE_KEYBOARD: {
1259 sessionVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1260 break;
1261 }
1262 default: {
1263 TLOGD(WmsLogTag::WMS_IMMS, "unsupported type %{public}u", type);
1264 return {};
1265 }
1266 }
1267
1268 for (auto& session : sessionVector) {
1269 if (!session->IsVisible()) {
1270 continue;
1271 }
1272 const WSRect rect = session->GetSessionRect();
1273 TLOGI(WmsLogTag::WMS_IMMS, "type: %{public}u, rect: %{public}s", type, rect.ToString().c_str());
1274 return rect;
1275 }
1276 return {};
1277 }
1278
GetSceneSession(int32_t persistentId)1279 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
1280 {
1281 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1282 auto iter = sceneSessionMap_.find(persistentId);
1283 if (iter == sceneSessionMap_.end()) {
1284 WLOGFD("Error found scene session with id: %{public}d", persistentId);
1285 return nullptr;
1286 }
1287 return iter->second;
1288 }
1289
GetMainSessionByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::vector<sptr<SceneSession>> & mainSessions)1290 void SceneSessionManager::GetMainSessionByBundleNameAndAppIndex(
1291 const std::string& bundleName, int32_t appIndex, std::vector<sptr<SceneSession>>& mainSessions)
1292 {
1293 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1294 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1295 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName &&
1296 sceneSession->GetSessionInfo().appIndex_ == appIndex &&
1297 SessionHelper::IsMainWindow(sceneSession->GetWindowType())) {
1298 mainSessions.push_back(sceneSession);
1299 }
1300 }
1301 }
1302
GetSceneSessionByName(const ComparedSessionInfo & info)1303 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const ComparedSessionInfo& info)
1304 {
1305 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1306 for (const auto &item : sceneSessionMap_) {
1307 auto sceneSession = item.second;
1308 if (sceneSession->GetSessionInfo().bundleName_ != info.bundleName_ ||
1309 sceneSession->GetSessionInfo().appIndex_ != info.appIndex_ ||
1310 sceneSession->GetSessionInfo().windowType_ != info.windowType_) {
1311 continue;
1312 }
1313 if (info.isAtomicService_) {
1314 if ((sceneSession->GetSessionInfo().moduleName_.empty() ||
1315 sceneSession->GetSessionInfo().moduleName_ == info.moduleName_) &&
1316 (sceneSession->GetSessionInfo().abilityName_.empty() ||
1317 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_)) {
1318 return sceneSession;
1319 }
1320 } else if (sceneSession->GetSessionInfo().moduleName_ == info.moduleName_ &&
1321 sceneSession->GetSessionInfo().abilityName_ == info.abilityName_) {
1322 return sceneSession;
1323 }
1324 }
1325 return nullptr;
1326 }
1327
GetSceneSessionByType(WindowType type)1328 sptr<SceneSession> SceneSessionManager::GetSceneSessionByType(WindowType type)
1329 {
1330 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1331 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1332 if (sceneSession && sceneSession->GetWindowType() == type) {
1333 return sceneSession;
1334 }
1335 }
1336 return nullptr;
1337 }
1338
GetSceneSessionByBundleName(const std::string & bundleName)1339 sptr<SceneSession> SceneSessionManager::GetSceneSessionByBundleName(const std::string& bundleName)
1340 {
1341 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1342 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1343 if (sceneSession && sceneSession->GetSessionInfo().bundleName_ == bundleName) {
1344 return sceneSession;
1345 }
1346 }
1347 return nullptr;
1348 }
1349
GetSceneSessionVectorByType(WindowType type,uint64_t displayId)1350 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(
1351 WindowType type, uint64_t displayId)
1352 {
1353 if (displayId == DISPLAY_ID_INVALID) {
1354 TLOGE(WmsLogTag::WMS_LIFE, "displayId is invalid");
1355 return {};
1356 }
1357 std::vector<sptr<SceneSession>> sceneSessionVector;
1358 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1359 for (const auto &item : sceneSessionMap_) {
1360 auto sceneSession = item.second;
1361 if (sceneSession->GetWindowType() == type &&
1362 sceneSession->GetSessionProperty() &&
1363 sceneSession->GetSessionProperty()->GetDisplayId() == displayId) {
1364 sceneSessionVector.emplace_back(sceneSession);
1365 }
1366 }
1367
1368 return sceneSessionVector;
1369 }
1370
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)1371 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
1372 sptr<WindowSessionProperty> property)
1373 {
1374 if (property == nullptr) {
1375 TLOGD(WmsLogTag::WMS_DIALOG, "Property is null, no need to update parent info");
1376 return WSError::WS_ERROR_NULLPTR;
1377 }
1378 if (sceneSession == nullptr) {
1379 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr");
1380 return WSError::WS_ERROR_NULLPTR;
1381 }
1382 auto parentPersistentId = property->GetParentPersistentId();
1383 sceneSession->SetParentPersistentId(parentPersistentId);
1384 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
1385 auto parentSession = GetSceneSession(parentPersistentId);
1386 if (parentSession == nullptr) {
1387 TLOGE(WmsLogTag::WMS_DIALOG, "Parent session is nullptr, parentId:%{public}d", parentPersistentId);
1388 return WSError::WS_ERROR_NULLPTR;
1389 }
1390 parentSession->BindDialogSessionTarget(sceneSession);
1391 parentSession->BindDialogToParentSession(sceneSession);
1392 sceneSession->SetParentSession(parentSession);
1393 TLOGI(WmsLogTag::WMS_DIALOG, "Update parent of dialog success, id %{public}d, parentId %{public}d",
1394 sceneSession->GetPersistentId(), parentPersistentId);
1395 }
1396 return WSError::WS_OK;
1397 }
1398
CreateSpecificSessionCallback()1399 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
1400 {
1401 sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
1402 if (specificCb == nullptr) {
1403 WLOGFE("SpecificSessionCallback is nullptr");
1404 return nullptr;
1405 }
1406 specificCb->onCreate_ = [this](const SessionInfo& sessionInfo, sptr<WindowSessionProperty> property) {
1407 return this->RequestSceneSession(sessionInfo, property);
1408 };
1409 specificCb->onDestroy_ = [this](const int32_t persistentId) {
1410 return this->DestroyAndDisconnectSpecificSessionInner(persistentId);
1411 };
1412 specificCb->onClearDisplayStatusBarTemporarilyFlags_ = [this] {
1413 this->ClearDisplayStatusBarTemporarilyFlags();
1414 };
1415 specificCb->onCameraFloatSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1416 this->UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
1417 };
1418 specificCb->onGetSceneSessionVectorByType_ = [this](WindowType type, uint64_t displayId) {
1419 return this->GetSceneSessionVectorByType(type, displayId);
1420 };
1421 specificCb->onUpdateAvoidArea_ = [this](int32_t persistentId) {
1422 this->UpdateAvoidArea(persistentId);
1423 };
1424 specificCb->onUpdateAvoidAreaByType_ = [this](int32_t persistentId, AvoidAreaType type) {
1425 this->UpdateAvoidAreaByType(persistentId, type);
1426 };
1427 specificCb->onGetStatusBarDefaultVisibilityByDisplayId_ = [this](DisplayId displayId) {
1428 return this->GetStatusBarDefaultVisibilityByDisplayId(displayId);
1429 };
1430 specificCb->onUpdateOccupiedAreaIfNeed_ = [this](const int32_t& persistentId) {
1431 this->UpdateOccupiedAreaIfNeed(persistentId);
1432 };
1433 specificCb->onWindowInfoUpdate_ = [this](int32_t persistentId, WindowUpdateType type) {
1434 this->NotifyWindowInfoChange(persistentId, type);
1435 };
1436 specificCb->onWindowInputPidChangeCallback_ = [this](int32_t windowId, bool startMoving) {
1437 this->NotifyMMIWindowPidChange(windowId, startMoving);
1438 };
1439 specificCb->onSessionTouchOutside_ = [this](int32_t persistentId) {
1440 this->NotifySessionTouchOutside(persistentId);
1441 };
1442 specificCb->onGetAINavigationBarArea_ = [this](uint64_t displayId) {
1443 return this->GetAINavigationBarArea(displayId);
1444 };
1445 specificCb->onOutsideDownEvent_ = [this](int32_t x, int32_t y) {
1446 this->OnOutsideDownEvent(x, y);
1447 };
1448 specificCb->onHandleSecureSessionShouldHide_ = [this](const sptr<SceneSession>& sceneSession) {
1449 return this->HandleSecureSessionShouldHide(sceneSession);
1450 };
1451 specificCb->onCameraSessionChange_ = [this](uint32_t accessTokenId, bool isShowing) {
1452 this->UpdateCameraWindowStatus(accessTokenId, isShowing);
1453 };
1454 specificCb->onSetSkipSelfWhenShowOnVirtualScreen_ = [this](uint64_t surfaceNodeId, bool isSkip) {
1455 this->SetSkipSelfWhenShowOnVirtualScreen(surfaceNodeId, isSkip);
1456 };
1457 specificCb->onPiPStateChange_ = [this](const std::string& bundleName, bool isForeground) {
1458 this->UpdatePiPWindowStateChanged(bundleName, isForeground);
1459 };
1460 specificCb->onUpdateGestureBackEnabled_ = [this](int32_t persistentId) {
1461 this->UpdateGestureBackEnabled(persistentId);
1462 };
1463 return specificCb;
1464 }
1465
SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId,bool isSkip)1466 void SceneSessionManager::SetSkipSelfWhenShowOnVirtualScreen(uint64_t surfaceNodeId, bool isSkip)
1467 {
1468 TLOGI(WmsLogTag::WMS_SCB, "surfaceNodeId: %{public}" PRIu64, surfaceNodeId);
1469 auto it = std::find(skipSurfaceNodeIds_.begin(), skipSurfaceNodeIds_.end(), surfaceNodeId);
1470 if (isSkip) {
1471 if (it == skipSurfaceNodeIds_.end()) {
1472 skipSurfaceNodeIds_.push_back(surfaceNodeId);
1473 } else {
1474 return;
1475 }
1476 } else {
1477 if (it != skipSurfaceNodeIds_.end()) {
1478 skipSurfaceNodeIds_.erase(it);
1479 } else {
1480 return;
1481 }
1482 }
1483 rsInterface_.SetVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
1484 }
1485
CreateKeyboardSessionCallback()1486 sptr<KeyboardSession::KeyboardSessionCallback> SceneSessionManager::CreateKeyboardSessionCallback()
1487 {
1488 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb =
1489 new (std::nothrow)KeyboardSession::KeyboardSessionCallback();
1490 if (keyboardCb == nullptr) {
1491 TLOGE(WmsLogTag::WMS_KEYBOARD, "KeyboardSessionCallback is nullptr");
1492 return keyboardCb;
1493 }
1494 keyboardCb->onGetSceneSession_ = [this](int32_t persistentId) {
1495 return this->GetSceneSession(persistentId);
1496 };
1497 keyboardCb->onGetFocusedSessionId_ = [this] {
1498 return this->GetFocusedSessionId();
1499 };
1500 keyboardCb->onCallingSessionIdChange_ = callingSessionIdChangeFunc_;
1501
1502 return keyboardCb;
1503 }
1504
CheckWindowId(int32_t windowId,int32_t & pid)1505 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t& pid)
1506 {
1507 if (!SessionPermission::IsSystemCalling()) {
1508 TLOGE(WmsLogTag::WMS_EVENT, "CheckWindowId permission denied!");
1509 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1510 }
1511
1512 auto task = [this, windowId, &pid]() -> WMError {
1513 pid = INVALID_PID;
1514 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1515 auto iter = sceneSessionMap_.find(windowId);
1516 if (iter == sceneSessionMap_.end()) {
1517 WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
1518 return WMError::WM_ERROR_INVALID_WINDOW;
1519 }
1520 auto sceneSession = iter->second;
1521 if (sceneSession == nullptr) {
1522 WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
1523 return WMError::WM_ERROR_INVALID_WINDOW;
1524 }
1525 pid = sceneSession->GetCallingPid();
1526 WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
1527 return WMError::WM_OK;
1528 };
1529 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
1530 }
1531
GetLockScreenZOrder()1532 uint32_t SceneSessionManager::GetLockScreenZOrder()
1533 {
1534 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1535 for (const auto& [persistentId, session] : sceneSessionMap_) {
1536 if (session && session->IsScreenLockWindow()) {
1537 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: found window %{public}d", persistentId);
1538 return session->GetZOrder() < DEFAULT_LOCK_SCREEN_ZORDER ? DEFAULT_LOCK_SCREEN_ZORDER :
1539 session->GetZOrder();
1540 }
1541 }
1542 TLOGE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not found");
1543 return DEFAULT_LOCK_SCREEN_ZORDER;
1544 }
1545
CheckUIExtensionCreation(int32_t windowId,uint32_t callingTokenId,const AppExecFwk::ElementName & element,AppExecFwk::ExtensionAbilityType extensionAbilityType,int32_t & pid)1546 WMError SceneSessionManager::CheckUIExtensionCreation(int32_t windowId, uint32_t callingTokenId,
1547 const AppExecFwk::ElementName& element, AppExecFwk::ExtensionAbilityType extensionAbilityType, int32_t& pid)
1548 {
1549 std::ostringstream ss;
1550 ss << "UIExtOnLockCheck" << "_" << windowId << "_" << callingTokenId;
1551 return taskScheduler_->PostSyncTask([this, windowId, callingTokenId, &element, extensionAbilityType, &pid]() {
1552 pid = INVALID_PID;
1553 auto sceneSession = GetSceneSession(windowId);
1554 if (sceneSession == nullptr) {
1555 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sceneSession(%{public}d) is nullptr", windowId);
1556 return WMError::WM_ERROR_INVALID_WINDOW;
1557 }
1558 pid = sceneSession->GetCallingPid();
1559 if (!IsScreenLocked()) {
1560 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not in lock screen");
1561 return WMError::WM_OK;
1562 }
1563 if (IsUserAuthPassed()) {
1564 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: auth passed");
1565 return WMError::WM_OK;
1566 }
1567 // 1. check window whether can show on main window
1568 if (!sceneSession->IsShowOnLockScreen(GetLockScreenZOrder())) {
1569 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: not called on lock screen");
1570 return WMError::WM_OK;
1571 }
1572 // 2. check permission
1573 if (!IsUIExtCanShowOnLockScreen(element, callingTokenId, extensionAbilityType)) {
1574 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: no permisson, window id %{public}d, %{public}d", windowId,
1575 callingTokenId);
1576 return WMError::WM_ERROR_INVALID_PERMISSION;
1577 }
1578 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: IsShowOnLockScreen: The caller permission has granted");
1579 return WMError::WM_OK;
1580 }, ss.str());
1581 }
1582
1583 // windowIds are all main window
OnNotifyAboveLockScreen(const std::vector<int32_t> & windowIds)1584 void SceneSessionManager::OnNotifyAboveLockScreen(const std::vector<int32_t>& windowIds)
1585 {
1586 taskScheduler_->PostSyncTask([this, &windowIds]() {
1587 // check every window
1588 for (auto windowId : windowIds) {
1589 auto sceneSession = GetSceneSession(windowId);
1590 if (!sceneSession) {
1591 TLOGNE(WmsLogTag::WMS_UIEXT, "UIExtOnLock: sesssion is null for %{public}d", windowId);
1592 continue;
1593 }
1594 TLOGNI(WmsLogTag::WMS_UIEXT, "UIExtOnLock: check for %{public}d", windowId);
1595 sceneSession->OnNotifyAboveLockScreen();
1596 }
1597 return WMError::WM_OK;
1598 }, __func__);
1599 }
1600
CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)1601 void SceneSessionManager::CreateKeyboardPanelSession(sptr<SceneSession> keyboardSession)
1602 {
1603 if (!isKeyboardPanelEnabled_) {
1604 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is not enabled");
1605 return;
1606 }
1607 if (keyboardSession == nullptr) {
1608 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr");
1609 return;
1610 }
1611 auto sessionProperty = keyboardSession->GetSessionProperty();
1612 if (sessionProperty == nullptr) {
1613 TLOGE(WmsLogTag::WMS_KEYBOARD, "sessionProperty is null");
1614 return;
1615 }
1616 DisplayId displayId = sessionProperty->GetDisplayId();
1617 const auto& panelVec = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_KEYBOARD_PANEL, displayId);
1618 sptr<SceneSession> panelSession;
1619 if (panelVec.size() > 1) {
1620 TLOGE(WmsLogTag::WMS_KEYBOARD, "Error size of keyboardPanel, size: %{public}zu", panelVec.size());
1621 return;
1622 } else if (panelVec.size() == 1) {
1623 panelSession = panelVec.front();
1624 TLOGI(WmsLogTag::WMS_KEYBOARD, "keyboardPanel is created, panelId:%{public}d", panelSession->GetPersistentId());
1625 } else {
1626 SessionInfo panelInfo = {
1627 .bundleName_ = "SCBKeyboardPanel",
1628 .moduleName_ = "SCBKeyboardPanel",
1629 .abilityName_ = "SCBKeyboardPanel",
1630 .isSystem_ = true,
1631 .sceneType_ = SceneType::SYSTEM_WINDOW_SCENE,
1632 .windowType_ = static_cast<uint32_t>(WindowType::WINDOW_TYPE_KEYBOARD_PANEL),
1633 .screenId_ = static_cast<uint64_t>(displayId),
1634 .isRotable_ = true,
1635 };
1636 static bool is2in1 = systemConfig_.uiType_ == UI_TYPE_PC;
1637 if (is2in1) {
1638 panelInfo.sceneType_ = SceneType::INPUT_SCENE;
1639 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel canvasNode");
1640 } else {
1641 TLOGI(WmsLogTag::WMS_KEYBOARD, "Set panel surfaceNode");
1642 }
1643 panelSession = RequestSceneSession(panelInfo, nullptr);
1644 if (panelSession == nullptr) {
1645 TLOGE(WmsLogTag::WMS_KEYBOARD, "PanelSession is nullptr");
1646 return;
1647 }
1648 }
1649 keyboardSession->BindKeyboardPanelSession(panelSession);
1650 panelSession->BindKeyboardSession(keyboardSession);
1651 TLOGI(WmsLogTag::WMS_KEYBOARD, "success, panelId:%{public}d, keyboardId:%{public}d",
1652 panelSession->GetPersistentId(), keyboardSession->GetPersistentId());
1653 }
1654
OnSCBSystemSessionBufferAvailable(WindowType type)1655 void SceneSessionManager::OnSCBSystemSessionBufferAvailable(WindowType type)
1656 {
1657 TLOGI(WmsLogTag::WMS_MULTI_USER, "In");
1658 if (type == WindowType::WINDOW_TYPE_KEYGUARD) {
1659 TLOGI(WmsLogTag::WMS_MULTI_USER, "On screen lock buffer available");
1660 }
1661 }
1662
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1663 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
1664 sptr<WindowSessionProperty> property)
1665 {
1666 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
1667 sptr<SceneSession> sceneSession = nullptr;
1668 if (sessionInfo.isSystem_) {
1669 sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
1670 WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
1671 if (sceneSession != nullptr &&
1672 static_cast<OHOS::Rosen::WindowType>(sessionInfo.windowType_) == WindowType::WINDOW_TYPE_KEYGUARD) {
1673 TLOGI(WmsLogTag::WMS_MULTI_USER, "Register screen lock buffer available");
1674 sceneSession->RegisterBufferAvailableCallback([this] {
1675 this->OnSCBSystemSessionBufferAvailable(WindowType::WINDOW_TYPE_KEYGUARD);
1676 });
1677 }
1678 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1679 sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
1680 if (sceneSession != nullptr) {
1681 TLOGI(WmsLogTag::WMS_MAIN, "Create MainSession, id: %{public}d", sceneSession->GetPersistentId());
1682 }
1683 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
1684 sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
1685 TLOGI(WmsLogTag::WMS_SUB, "Create SubSession, type: %{public}d", property->GetWindowType());
1686 } else if (property != nullptr && property->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1687 sptr<KeyboardSession::KeyboardSessionCallback> keyboardCb = CreateKeyboardSessionCallback();
1688 sceneSession = new (std::nothrow) KeyboardSession(sessionInfo, specificCb, keyboardCb);
1689 CreateKeyboardPanelSession(sceneSession);
1690 TLOGI(WmsLogTag::WMS_KEYBOARD, "Create KeyboardSession, type: %{public}d", property->GetWindowType());
1691 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
1692 sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
1693 TLOGI(WmsLogTag::WMS_SYSTEM, "Create SystemSession, type: %{public}d", property->GetWindowType());
1694 } else {
1695 TLOGE(WmsLogTag::WMS_LIFE, "Invalid window type");
1696 }
1697 if (sceneSession != nullptr) {
1698 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
1699 sceneSession->isKeyboardPanelEnabled_ = isKeyboardPanelEnabled_;
1700 sceneSession->RegisterForceSplitListener([this](const std::string& bundleName) {
1701 return this->GetAppForceLandscapeConfig(bundleName);
1702 });
1703 sceneSession->SetUpdatePrivateStateAndNotifyFunc([this](int32_t persistentId) {
1704 this->UpdatePrivateStateAndNotify(persistentId);
1705 });
1706 sceneSession->SetNotifyVisibleChangeFunc([this](int32_t persistentId) {
1707 this->NotifyVisibleChange(persistentId);
1708 });
1709 sceneSession->SetIsLastFrameLayoutFinishedFunc([this](bool& isLayoutFinished) {
1710 return this->IsLastFrameLayoutFinished(isLayoutFinished);
1711 });
1712 DragResizeType dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1713 GetAppDragResizeType(sessionInfo.bundleName_, dragResizeType);
1714 sceneSession->SetAppDragResizeType(dragResizeType);
1715 }
1716 return sceneSession;
1717 }
1718
GetEffectiveDragResizeType(DragResizeType & dragResizeType)1719 void SceneSessionManager::GetEffectiveDragResizeType(DragResizeType& dragResizeType)
1720 {
1721 if (dragResizeType != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1722 return;
1723 }
1724 if (systemConfig_.freeMultiWindowSupport_) {
1725 dragResizeType = DragResizeType::RESIZE_WHEN_DRAG_END;
1726 } else {
1727 dragResizeType = DragResizeType::RESIZE_EACH_FRAME;
1728 }
1729 }
1730
SetGlobalDragResizeType(DragResizeType dragResizeType)1731 WMError SceneSessionManager::SetGlobalDragResizeType(DragResizeType dragResizeType)
1732 {
1733 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1734 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1735 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1736 return WMError::WM_ERROR_INVALID_PERMISSION;
1737 }
1738 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1739 globalDragResizeType_ = dragResizeType;
1740 taskScheduler_->PostAsyncTask([this] {
1741 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1742 for (const auto& [_, sceneSession] : sceneSessionMap_) {
1743 if (sceneSession != nullptr && WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1744 const std::string& bundleName = sceneSession->GetSessionInfo().bundleName_;
1745 DragResizeType appDragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1746 GetAppDragResizeType(bundleName, appDragResizeType);
1747 TLOGND(WmsLogTag::WMS_LAYOUT, "SetGlobalDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1748 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), appDragResizeType);
1749 sceneSession->SetAppDragResizeType(appDragResizeType);
1750 }
1751 }
1752 }, __func__);
1753 return WMError::WM_OK;
1754 }
1755
GetGlobalDragResizeType(DragResizeType & dragResizeType)1756 WMError SceneSessionManager::GetGlobalDragResizeType(DragResizeType& dragResizeType)
1757 {
1758 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1759 dragResizeType = globalDragResizeType_;
1760 GetEffectiveDragResizeType(dragResizeType);
1761 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d", dragResizeType);
1762 return WMError::WM_OK;
1763 }
1764
SetAppDragResizeType(const std::string & bundleName,DragResizeType dragResizeType)1765 WMError SceneSessionManager::SetAppDragResizeType(const std::string& bundleName, DragResizeType dragResizeType)
1766 {
1767 TLOGD(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1768 dragResizeType, bundleName.c_str());
1769 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
1770 TLOGE(WmsLogTag::WMS_LAYOUT, "permission denied!");
1771 return WMError::WM_ERROR_INVALID_PERMISSION;
1772 }
1773 return SetAppDragResizeTypeInner(bundleName, dragResizeType);
1774 }
1775
SetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType dragResizeType)1776 WMError SceneSessionManager::SetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType dragResizeType)
1777 {
1778 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1779 dragResizeType, bundleName.c_str());
1780 if (bundleName.empty()) {
1781 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1782 return WMError::WM_ERROR_INVALID_PARAM;
1783 }
1784 std::lock_guard<std::mutex> dragResizeTypeLock(dragResizeTypeMutex_);
1785 appDragResizeTypeMap_[bundleName] = dragResizeType;
1786 GetAppDragResizeTypeInner(bundleName, dragResizeType);
1787 taskScheduler_->PostAsyncTask([this, bundleName, dragResizeType] {
1788 auto sceneSession = GetSceneSessionByBundleName(bundleName);
1789 if (sceneSession != nullptr) {
1790 TLOGNI(WmsLogTag::WMS_LAYOUT, "SetAppDragResizeType persistentId: %{public}d, bundleName: %{public}s, "
1791 "dragResizeType: %{public}d", sceneSession->GetPersistentId(), bundleName.c_str(), dragResizeType);
1792 sceneSession->SetAppDragResizeType(dragResizeType);
1793 }
1794 }, __func__);
1795 return WMError::WM_OK;
1796 }
1797
GetAppDragResizeType(const std::string & bundleName,DragResizeType & dragResizeType)1798 WMError SceneSessionManager::GetAppDragResizeType(const std::string& bundleName, DragResizeType& dragResizeType)
1799 {
1800 std::lock_guard<std::mutex> lock(dragResizeTypeMutex_);
1801 return GetAppDragResizeTypeInner(bundleName, dragResizeType);
1802 }
1803
GetAppDragResizeTypeInner(const std::string & bundleName,DragResizeType & dragResizeType)1804 WMError SceneSessionManager::GetAppDragResizeTypeInner(const std::string& bundleName, DragResizeType& dragResizeType)
1805 {
1806 if (bundleName.empty()) {
1807 TLOGE(WmsLogTag::WMS_LAYOUT, "bundleName empty");
1808 return WMError::WM_ERROR_INVALID_PARAM;
1809 }
1810 if (globalDragResizeType_ != DragResizeType::RESIZE_TYPE_UNDEFINED) {
1811 TLOGI(WmsLogTag::WMS_LAYOUT, "use global value");
1812 dragResizeType = globalDragResizeType_;
1813 return WMError::WM_OK;
1814 }
1815 dragResizeType = DragResizeType::RESIZE_TYPE_UNDEFINED;
1816 if (auto iter = appDragResizeTypeMap_.find(bundleName); iter != appDragResizeTypeMap_.end()) {
1817 dragResizeType = iter->second;
1818 }
1819 GetEffectiveDragResizeType(dragResizeType);
1820 TLOGI(WmsLogTag::WMS_LAYOUT, "dragResizeType: %{public}d, bundleName: %{public}s",
1821 dragResizeType, bundleName.c_str());
1822 return WMError::WM_OK;
1823 }
1824
GetSceneSessionBySessionInfo(const SessionInfo & sessionInfo)1825 sptr<SceneSession> SceneSessionManager::GetSceneSessionBySessionInfo(const SessionInfo& sessionInfo)
1826 {
1827 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_) {
1828 auto session = GetSceneSession(sessionInfo.persistentId_);
1829 if (session != nullptr) {
1830 TLOGI(WmsLogTag::WMS_LIFE, "get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1831 return session;
1832 }
1833
1834 if (WindowHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
1835 TLOGD(WmsLogTag::WMS_LIFE, "mainWindow bundleName: %{public}s, moduleName: %{public}s, "
1836 "abilityName: %{public}s, appIndex: %{public}d",
1837 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1838 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_);
1839 ComparedSessionInfo compareSessionInfo = { sessionInfo.bundleName_, sessionInfo.moduleName_, sessionInfo.abilityName_,
1840 sessionInfo.appIndex_, sessionInfo.windowType_, sessionInfo.isAtomicService_ };
1841 auto sceneSession = GetSceneSessionByName(compareSessionInfo);
1842 bool isSingleStart = sceneSession && sceneSession->GetAbilityInfo() &&
1843 sceneSession->GetAbilityInfo()->launchMode == AppExecFwk::LaunchMode::SINGLETON;
1844 if (isSingleStart) {
1845 TLOGD(WmsLogTag::WMS_LIFE, "get exist singleton session persistentId: %{public}d",
1846 sessionInfo.persistentId_);
1847 return sceneSession;
1848 }
1849 }
1850 }
1851 return nullptr;
1852 }
1853
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)1854 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
1855 sptr<WindowSessionProperty> property)
1856 {
1857 const char* const where = __func__;
1858 auto task = [this, sessionInfo, property, where] {
1859 if (auto session = GetSceneSessionBySessionInfo(sessionInfo)) {
1860 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1861 return session;
1862 }
1863 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: appName: [%{public}s %{public}s %{public}s] "
1864 "appIndex %{public}d, type %{public}u system %{public}u, isPersistentRecover %{public}u",
1865 where, sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
1866 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
1867 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
1868 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
1869 if (sceneSession == nullptr) {
1870 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is nullptr!");
1871 return sceneSession;
1872 }
1873 InitSceneSession(sceneSession, sessionInfo, property);
1874 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1875 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s: ancoSceneState: %{public}d",
1876 where, sceneSession->GetSessionInfo().ancoSceneState);
1877 bool isPreHandleSuccess = PreHandleCollaboratorStartAbility(sceneSession);
1878 const auto& sessionAffinity = sceneSession->GetSessionInfo().sessionAffinity;
1879 if (auto reusedSceneSession = SceneSessionManager::GetInstance().FindSessionByAffinity(sessionAffinity)) {
1880 TLOGNI(WmsLogTag::WMS_LIFE,
1881 "%{public}s: session reuse id:%{public}d type:%{public}d affinity:%{public}s",
1882 where, reusedSceneSession->GetPersistentId(),
1883 reusedSceneSession->GetWindowType(), sessionAffinity.c_str());
1884 NotifySessionUpdate(reusedSceneSession->GetSessionInfo(), ActionType::SINGLE_START);
1885 return reusedSceneSession;
1886 }
1887 if (isPreHandleSuccess) {
1888 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
1889 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
1890 }
1891 }
1892 {
1893 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1894 sceneSessionMap_.insert({ sceneSession->GetPersistentId(), sceneSession });
1895 }
1896 PerformRegisterInRequestSceneSession(sceneSession);
1897 TLOGI(WmsLogTag::WMS_LIFE, "RequestSceneSession id: %{public}d, type: %{public}d",
1898 sceneSession->GetPersistentId(), sceneSession->GetWindowType());
1899 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1900 return sceneSession;
1901 };
1902 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1903 }
1904
InitSceneSession(sptr<SceneSession> & sceneSession,const SessionInfo & sessionInfo,const sptr<WindowSessionProperty> & property)1905 void SceneSessionManager::InitSceneSession(sptr<SceneSession>& sceneSession, const SessionInfo& sessionInfo,
1906 const sptr<WindowSessionProperty>& property)
1907 {
1908 auto callerSession = GetSceneSession(sessionInfo.callerPersistentId_);
1909 DisplayId curDisplayId = DISPLAY_ID_INVALID;
1910 if (sessionInfo.screenId_ != SCREEN_ID_INVALID) {
1911 curDisplayId = sessionInfo.screenId_;
1912 } else if (callerSession) {
1913 auto callerSessionProperty = callerSession->GetSessionProperty();
1914 if (callerSessionProperty) {
1915 curDisplayId = callerSessionProperty->GetDisplayId();
1916 }
1917 }
1918 auto sessionProperty = sceneSession->GetSessionProperty();
1919 if (sessionProperty) {
1920 sessionProperty->SetDisplayId(curDisplayId);
1921 sceneSession->SetScreenId(curDisplayId);
1922 TLOGD(WmsLogTag::WMS_LIFE, "synchronous screenId with displayid %{public}" PRIu64,
1923 curDisplayId);
1924 }
1925 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
1926 sceneSession->RegisterIsScreenLockedCallback([this] { return IsScreenLocked(); });
1927 if (sessionInfo.isSystem_) {
1928 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1929 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1930 auto rootContext = rootSceneContextWeak_.lock();
1931 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1932 } else {
1933 TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d, bundleName: %{public}s, "
1934 "moduleName: %{public}s, abilityName: %{public}s want: %{public}s", sceneSession->GetPersistentId(),
1935 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1936 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1937 }
1938 RegisterSessionExceptionFunc(sceneSession);
1939 // Skip FillSessionInfo when atomicService free-install start.
1940 if (!IsAtomicServiceFreeInstall(sessionInfo)) {
1941 FillSessionInfo(sceneSession);
1942 }
1943 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", sceneSession->GetPersistentId());
1944 if (property != nullptr && WindowHelper::IsPipWindow(property->GetWindowType())) {
1945 sceneSession->SetPiPTemplateInfo(property->GetPiPTemplateInfo());
1946 }
1947 sceneSession->SetSystemConfig(systemConfig_);
1948 sceneSession->SetSnapshotScale(snapshotScale_);
1949 UpdateParentSessionForDialog(sceneSession, property);
1950 }
1951
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)1952 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1953 {
1954 sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
1955 if (info == nullptr) {
1956 WLOGFE("new info failed");
1957 return;
1958 }
1959 info->action_ = action;
1960 info->abilityName_ = sessionInfo.abilityName_;
1961 info->bundleName_ = sessionInfo.bundleName_;
1962 info->toScreenId_ = sessionInfo.screenId_;
1963 info->fromScreenId_ = fromScreenId;
1964 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1965 WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
1966 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1967 }
1968
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)1969 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1970 {
1971 RegisterSessionSnapshotFunc(sceneSession);
1972 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1973 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1974 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1975 RegisterGetStateFromManagerFunc(sceneSession);
1976 RegisterSessionChangeByActionNotifyManagerFunc(sceneSession);
1977 RegisterAcquireRotateAnimationConfigFunc(sceneSession);
1978 }
1979
UpdateSceneSessionWant(const SessionInfo & sessionInfo)1980 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1981 {
1982 if (sessionInfo.persistentId_ != 0) {
1983 auto session = GetSceneSession(sessionInfo.persistentId_);
1984 if (session != nullptr && sessionInfo.want != nullptr) {
1985 TLOGI(WmsLogTag::WMS_MAIN, "Got session id:%{public}d", sessionInfo.persistentId_);
1986 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1987 session->SetSessionInfoWant(sessionInfo.want);
1988 TLOGI(WmsLogTag::WMS_MAIN, "Want updated, id:%{public}d", sessionInfo.persistentId_);
1989 } else {
1990 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1991 }
1992 } else {
1993 TLOGI(WmsLogTag::WMS_MAIN, "Got session fail(%{public}d), id:%{public}d",
1994 session == nullptr, sessionInfo.persistentId_);
1995 }
1996 } else {
1997 TLOGI(WmsLogTag::WMS_MAIN, "sessionInfo.Id == 0");
1998 }
1999 }
2000
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)2001 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
2002 {
2003 if (session != nullptr) {
2004 if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2005 FillSessionInfo(session);
2006 if (CheckCollaboratorType(session->GetCollaboratorType())) {
2007 PreHandleCollaborator(session, persistentId);
2008 }
2009 }
2010 }
2011 }
2012
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)2013 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
2014 {
2015 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
2016 if (abilitySessionInfo == nullptr) {
2017 WLOGFE("abilitySessionInfo is nullptr");
2018 return nullptr;
2019 }
2020 auto sessionInfo = scnSession->GetSessionInfo();
2021 sptr<ISession> iSession(scnSession);
2022 abilitySessionInfo->sessionToken = iSession->AsObject();
2023 abilitySessionInfo->identityToken = std::to_string(std::chrono::time_point_cast<std::chrono::milliseconds>(
2024 std::chrono::system_clock::now()).time_since_epoch().count());
2025 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
2026 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
2027 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
2028 abilitySessionInfo->persistentId = scnSession->GetPersistentId();
2029 abilitySessionInfo->requestCode = sessionInfo.requestCode;
2030 abilitySessionInfo->resultCode = sessionInfo.resultCode;
2031 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
2032 abilitySessionInfo->startSetting = sessionInfo.startSetting;
2033 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
2034 abilitySessionInfo->userId = currentUserId_;
2035 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
2036 abilitySessionInfo->processOptions = sessionInfo.processOptions;
2037 if (sessionInfo.want != nullptr) {
2038 abilitySessionInfo->want = *sessionInfo.want;
2039 } else {
2040 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
2041 sessionInfo.moduleName_);
2042 }
2043 int appIndex = abilitySessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
2044 bool hasAppIndex = abilitySessionInfo->want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY);
2045 if (hasAppIndex && sessionInfo.appIndex_ != appIndex) {
2046 TLOGW(WmsLogTag::WMS_LIFE, "appIndex not match want.appIndex:%{public}d, sessionInfo.appIndex_:%{public}d",
2047 appIndex, sessionInfo.appIndex_);
2048 }
2049 if (!hasAppIndex && sessionInfo.appIndex_ > 0) {
2050 TLOGI(WmsLogTag::WMS_LIFE, "want.appIndex is null, set want.appIndex:%{public}d", sessionInfo.appIndex_);
2051 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, sessionInfo.appIndex_);
2052 }
2053 auto sessionProperty = scnSession->GetSessionProperty();
2054 if (sessionProperty) {
2055 abilitySessionInfo->want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID,
2056 static_cast<int>(sessionProperty->GetDisplayId()));
2057 }
2058 if (sessionInfo.callState_ >= static_cast<uint32_t>(AAFwk::CallToState::UNKNOW) &&
2059 sessionInfo.callState_ <= static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2060 abilitySessionInfo->state = static_cast<AAFwk::CallToState>(sessionInfo.callState_);
2061 } else {
2062 TLOGW(WmsLogTag::WMS_LIFE, "Invalid callState:%{public}d", sessionInfo.callState_);
2063 }
2064 return abilitySessionInfo;
2065 }
2066
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)2067 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
2068 {
2069 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
2070 isPrepareTerminate = false;
2071 TLOGE(WmsLogTag::WMS_MAIN, "not support prepareTerminate, Id:%{public}d", persistentId);
2072 return WSError::WS_OK;
2073 }
2074 auto sceneSession = GetSceneSession(persistentId);
2075 if (sceneSession == nullptr) {
2076 TLOGE(WmsLogTag::WMS_MAIN, "sceneSession is null, Id:%{public}d", persistentId);
2077 isPrepareTerminate = false;
2078 return WSError::WS_ERROR_NULLPTR;
2079 }
2080 auto sceneSessionInfo = SetAbilitySessionInfo(sceneSession);
2081 if (sceneSessionInfo == nullptr) {
2082 TLOGE(WmsLogTag::WMS_MAIN, "sceneSessionInfo is null, Id:%{public}d", persistentId);
2083 isPrepareTerminate = false;
2084 return WSError::WS_ERROR_NULLPTR;
2085 }
2086 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
2087 PrepareTerminateAbilityBySCB(sceneSessionInfo, isPrepareTerminate);
2088 TLOGI(WmsLogTag::WMS_MAIN, "Id:%{public}d isPrepareTerminate:%{public}d "
2089 "errorCode:%{public}d", persistentId, isPrepareTerminate, errorCode);
2090 return WSError::WS_OK;
2091 }
2092
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)2093 WSError SceneSessionManager::RequestSceneSessionActivation(const sptr<SceneSession>& sceneSession, bool isNewActive)
2094 {
2095 wptr<SceneSession> weakSceneSession(sceneSession);
2096 auto task = [this, weakSceneSession, isNewActive]() {
2097 sptr<SceneSession> scnSession = weakSceneSession.promote();
2098 if (scnSession == nullptr) {
2099 TLOGE(WmsLogTag::WMS_MAIN, "Request active session is nullptr");
2100 return WSError::WS_ERROR_NULLPTR;
2101 }
2102 auto persistentId = scnSession->GetPersistentId();
2103 if (!Session::IsScbCoreEnabled()) {
2104 scnSession->SetForegroundInteractiveStatus(true);
2105 }
2106 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
2107 TLOGI(WmsLogTag::WMS_MAIN, "Request active id:%{public}d system:%{public}u isNewActive:%{public}d",
2108 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_), isNewActive);
2109 if (!GetSceneSession(persistentId)) {
2110 TLOGE(WmsLogTag::WMS_MAIN, "Request active session invalid by %{public}d", persistentId);
2111 return WSError::WS_ERROR_INVALID_SESSION;
2112 }
2113 auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive);
2114 if (ret == WSError::WS_OK) {
2115 scnSession->SetExitSplitOnBackground(false);
2116 }
2117 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
2118 return ret;
2119 };
2120 std::string taskName = "RequestSceneSessionActivation:PID:" +
2121 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2122 taskScheduler_->PostAsyncTask(task, taskName);
2123 return WSError::WS_OK;
2124 }
2125
IsKeyboardForeground()2126 bool SceneSessionManager::IsKeyboardForeground()
2127 {
2128 bool isKeyboardForeground = false;
2129 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2130 for (const auto &item : sceneSessionMap_) {
2131 auto sceneSession = item.second;
2132 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2133 isKeyboardForeground = sceneSession->IsSessionForeground();
2134 break;
2135 }
2136 }
2137
2138 return isKeyboardForeground;
2139 }
2140
RequestInputMethodCloseKeyboard(const int32_t persistentId)2141 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
2142 {
2143 auto sceneSession = GetSceneSession(persistentId);
2144 if (sceneSession == nullptr) {
2145 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
2146 return;
2147 }
2148 // Hide keyboard when app is cold started, if keyboard is showing and screen is unlocked.
2149 if (!sceneSession->IsSessionValid() && IsKeyboardForeground() &&
2150 !sceneSession->GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED)) {
2151 TLOGI(WmsLogTag::WMS_KEYBOARD, "Session is invalid, id: %{public}d state: %{public}u",
2152 persistentId, sceneSession->GetSessionState());
2153 sceneSession->RequestHideKeyboard(true);
2154 }
2155 }
2156
StartUIAbilityBySCB(sptr<SceneSession> & scnSession)2157 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<SceneSession>& scnSession)
2158 {
2159 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2160 if (abilitySessionInfo == nullptr) {
2161 return ERR_NULL_OBJECT;
2162 }
2163 return StartUIAbilityBySCB(abilitySessionInfo);
2164 }
2165
StartUIAbilityBySCB(sptr<AAFwk::SessionInfo> & abilitySessionInfo)2166 int32_t SceneSessionManager::StartUIAbilityBySCB(sptr<AAFwk::SessionInfo>& abilitySessionInfo)
2167 {
2168 bool isColdStart = false;
2169 return AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(abilitySessionInfo, isColdStart);
2170 }
2171
ChangeUIAbilityVisibilityBySCB(sptr<SceneSession> & scnSession,bool visibility)2172 int32_t SceneSessionManager::ChangeUIAbilityVisibilityBySCB(sptr<SceneSession>& scnSession, bool visibility)
2173 {
2174 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2175 if (abilitySessionInfo == nullptr) {
2176 return ERR_NULL_OBJECT;
2177 }
2178 return AAFwk::AbilityManagerClient::GetInstance()->ChangeUIAbilityVisibilityBySCB(abilitySessionInfo, visibility);
2179 }
2180
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive)2181 WSError SceneSessionManager::RequestSceneSessionActivationInner(
2182 sptr<SceneSession>& scnSession, bool isNewActive)
2183 {
2184 auto persistentId = scnSession->GetPersistentId();
2185 RequestInputMethodCloseKeyboard(persistentId);
2186 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2187 scnSession->SetIsStarting(true);
2188 scnSession->SetStartingBeforeVisible(true);
2189 }
2190 if (WindowHelper::IsMainWindow(scnSession->GetWindowType()) && scnSession->IsFocusedOnShow()) {
2191 if (Session::IsScbCoreEnabled()) {
2192 if (scnSession->IsVisibleForeground()) {
2193 RequestSessionFocusImmediately(persistentId);
2194 } else {
2195 PostProcessFocusState state = { true, true, FocusChangeReason::SCB_START_APP };
2196 scnSession->SetPostProcessFocusState(state);
2197 }
2198 } else {
2199 RequestSessionFocusImmediately(persistentId);
2200 }
2201 }
2202 if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
2203 FillSessionInfo(scnSession);
2204 if (!PreHandleCollaborator(scnSession, persistentId)) {
2205 TLOGE(WmsLogTag::WMS_LIFE, "persistentId: %{public}d, ancoSceneState: %{public}d",
2206 persistentId, scnSession->GetSessionInfo().ancoSceneState);
2207 scnSession->NotifySessionExceptionInner(SetAbilitySessionInfo(scnSession), true);
2208 return WSError::WS_ERROR_PRE_HANDLE_COLLABORATOR_FAILED;
2209 }
2210 }
2211 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2212 if (!scnSessionInfo) {
2213 TLOGE(WmsLogTag::WMS_LIFE, "create AbilityInfo fail id %{public}d", persistentId);
2214 return WSError::WS_ERROR_NULLPTR;
2215 }
2216 scnSession->NotifyActivation();
2217 scnSessionInfo->isNewWant = isNewActive;
2218 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2219 scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
2220 scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
2221 }
2222 TLOGI(WmsLogTag::WMS_LIFE, "id %{public}d want-ability: %{public}s, bundle: %{public}s, "
2223 "module: %{public}s, uri: %{public}s, appIndex: %{public}d.", persistentId,
2224 scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
2225 scnSessionInfo->want.GetElement().GetBundleName().c_str(),
2226 scnSessionInfo->want.GetElement().GetModuleName().c_str(),
2227 scnSessionInfo->want.GetElement().GetURI().c_str(),
2228 scnSessionInfo->want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0));
2229 int32_t errCode = ERR_OK;
2230 bool isColdStart = false;
2231 bool isAppSupportPhoneInPc = false;
2232 auto sessionProperty = scnSession->GetSessionProperty();
2233 if (sessionProperty != nullptr) {
2234 isAppSupportPhoneInPc = sessionProperty->GetIsAppSupportPhoneInPc();
2235 }
2236 if (systemConfig_.backgroundswitch == false || isAppSupportPhoneInPc) {
2237 TLOGI(WmsLogTag::WMS_MAIN, "Begin StartUIAbility: %{public}d system: %{public}u", persistentId,
2238 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2239 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2240 } else {
2241 TLOGI(WmsLogTag::WMS_MAIN, "Background switch on, isNewActive %{public}d state %{public}u",
2242 isNewActive, scnSession->GetSessionState());
2243 if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
2244 scnSession->GetSessionState() == SessionState::STATE_END) {
2245 TLOGI(WmsLogTag::WMS_MAIN, "Call StartUIAbility: %{public}d system: %{public}u", persistentId,
2246 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2247 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo, isColdStart);
2248 } else {
2249 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionForeground: %{public}d", persistentId);
2250 scnSession->NotifySessionForeground(1, true);
2251 }
2252 }
2253 auto sessionInfo = scnSession->GetSessionInfo();
2254 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2255 WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
2256 }
2257 NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
2258
2259 if (errCode != ERR_OK) {
2260 TLOGI(WmsLogTag::WMS_MAIN, "failed! errCode: %{public}d", errCode);
2261 scnSession->NotifySessionExceptionInner(scnSessionInfo, true, false, true);
2262 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
2263 startUIAbilityErrorFunc_(
2264 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
2265 }
2266 }
2267 if (isColdStart) {
2268 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
2269 scnSessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
2270 scnSession->SetClientIdentityToken(scnSessionInfo->identityToken);
2271 scnSession->ResetSessionConnectState();
2272 scnSession->ResetIsActive();
2273 }
2274 return WSError::WS_OK;
2275 }
2276
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)2277 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
2278 sptr<AAFwk::SessionInfo>& scnSessionInfo)
2279 {
2280 if (scnSession == nullptr || scnSessionInfo == nullptr) {
2281 return;
2282 }
2283 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2284 NotifyLoadAbility(scnSession->GetCollaboratorType(),
2285 scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
2286 NotifyUpdateSessionInfo(scnSession);
2287 NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2288 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
2289 }
2290 }
2291
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop,const bool isSaveSnapshot)2292 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
2293 const bool isDelegator, const bool isToDesktop, const bool isSaveSnapshot)
2294 {
2295 wptr<SceneSession> weakSceneSession(sceneSession);
2296 auto task = [this, weakSceneSession, isDelegator, isToDesktop, isSaveSnapshot]() {
2297 auto scnSession = weakSceneSession.promote();
2298 if (scnSession == nullptr) {
2299 TLOGE(WmsLogTag::WMS_MAIN, "session is nullptr");
2300 return WSError::WS_ERROR_NULLPTR;
2301 }
2302 auto persistentId = scnSession->GetPersistentId();
2303 TLOGI(WmsLogTag::WMS_MAIN, "Request background id:%{public}d isDelegator:%{public}d "
2304 "isToDesktop:%{public}d isSaveSnapshot:%{public}d",
2305 persistentId, isDelegator, isToDesktop, isSaveSnapshot);
2306 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
2307 scnSession->SetActive(false);
2308
2309 if (isToDesktop) {
2310 auto info = scnSession->GetSessionInfo();
2311 info.callerToken_ = nullptr;
2312 info.callingTokenId_ = 0;
2313 scnSession->SetSessionInfo(info);
2314 }
2315
2316 scnSession->BackgroundTask(isSaveSnapshot);
2317 if (!GetSceneSession(persistentId)) {
2318 TLOGE(WmsLogTag::WMS_MAIN, "Request background session invalid by %{public}d", persistentId);
2319 return WSError::WS_ERROR_INVALID_SESSION;
2320 }
2321 if (persistentId == brightnessSessionId_) {
2322 UpdateBrightness(focusedSessionId_);
2323 }
2324 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2325 if (!scnSessionInfo) {
2326 TLOGE(WmsLogTag::WMS_MAIN, "Create Ability info failed, id %{public}d", persistentId);
2327 return WSError::WS_ERROR_NULLPTR;
2328 }
2329 bool isPcAppInpad = false;
2330 bool isAppSupportPhoneInPc = false;
2331 auto property = scnSession->GetSessionProperty();
2332 if (property) {
2333 isPcAppInpad = property->GetIsPcAppInPad();
2334 isAppSupportPhoneInPc = property->GetIsAppSupportPhoneInPc();
2335 }
2336 if ((systemConfig_.backgroundswitch && !isAppSupportPhoneInPc) || isPcAppInpad) {
2337 TLOGI(WmsLogTag::WMS_MAIN, "NotifySessionBackground: %{public}d", persistentId);
2338 scnSession->NotifySessionBackground(1, true, true);
2339 } else {
2340 TLOGI(WmsLogTag::WMS_MAIN, "begin MinimzeUIAbility: %{public}d system: %{public}u",
2341 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2342 if (!isDelegator) {
2343 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2344 } else {
2345 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
2346 }
2347 }
2348
2349 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
2350 auto sessionInfo = scnSession->GetSessionInfo();
2351 WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
2352 }
2353 return WSError::WS_OK;
2354 };
2355 std::string taskName = "RequestSceneSessionBackground:PID:" +
2356 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
2357 taskScheduler_->PostAsyncTask(task, taskName);
2358 return WSError::WS_OK;
2359 }
2360
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)2361 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
2362 {
2363 wptr<SceneSession> weakSceneSession(sceneSession);
2364 auto task = [this, weakSceneSession, interactive]() {
2365 auto scnSession = weakSceneSession.promote();
2366 if (scnSession == nullptr) {
2367 WLOGFE("session is nullptr");
2368 return;
2369 }
2370 auto persistentId = scnSession->GetPersistentId();
2371 WLOGFI("NotifyForeInteractive id: %{public}d, status: %{public}d", persistentId, interactive);
2372 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
2373 if (!GetSceneSession(persistentId)) {
2374 WLOGFE("session is invalid with %{public}d", persistentId);
2375 return;
2376 }
2377 scnSession->NotifyForegroundInteractiveStatus(interactive);
2378 };
2379
2380 taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
2381 }
2382
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)2383 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
2384 {
2385 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
2386 if (scnSession == nullptr) {
2387 TLOGE(WmsLogTag::WMS_DIALOG, "session is nullptr");
2388 return WSError::WS_ERROR_NULLPTR;
2389 }
2390 if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2391 TLOGI(WmsLogTag::WMS_DIALOG, "Begin to destroy dialog, parentId: %{public}d", scnSession->GetPersistentId());
2392 auto dialogVec = scnSession->GetDialogVector();
2393 for (auto dialog : dialogVec) {
2394 if (dialog == nullptr) {
2395 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
2396 continue;
2397 }
2398 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
2399 if (sceneSession == nullptr) {
2400 TLOGE(WmsLogTag::WMS_DIALOG, "dialog is invalid, id: %{public}d", dialog->GetPersistentId());
2401 return WSError::WS_ERROR_INVALID_SESSION;
2402 }
2403 WindowDestroyNotifyVisibility(sceneSession);
2404 dialog->NotifyDestroy();
2405 dialog->Disconnect();
2406
2407 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
2408 if (dialogSceneSession != nullptr) {
2409 dialogSceneSession->ClearSpecificSessionCbMap();
2410 }
2411 {
2412 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2413 EraseSceneSessionAndMarkDirtyLocked(dialog->GetPersistentId());
2414 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
2415 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
2416 }
2417 }
2418 scnSession->ClearDialogVector();
2419 return WSError::WS_OK;
2420 }
2421 return WSError::WS_ERROR_INVALID_SESSION;
2422 }
2423
DestroySubSession(const sptr<SceneSession> & sceneSession)2424 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
2425 {
2426 if (sceneSession == nullptr) {
2427 WLOGFW("sceneSession is nullptr");
2428 return;
2429 }
2430 for (const auto& elem : sceneSession->GetSubSession()) {
2431 if (elem != nullptr) {
2432 const auto& persistentId = elem->GetPersistentId();
2433 TLOGI(WmsLogTag::WMS_SUB, "DestroySubSession, id: %{public}d", persistentId);
2434 DestroyAndDisconnectSpecificSessionInner(persistentId);
2435 }
2436 }
2437 }
2438
DestroyToastSession(const sptr<SceneSession> & sceneSession)2439 void SceneSessionManager::DestroyToastSession(const sptr<SceneSession>& sceneSession)
2440 {
2441 if (sceneSession == nullptr) {
2442 TLOGW(WmsLogTag::WMS_LIFE, "ToastSession is nullptr");
2443 return;
2444 }
2445 for (const auto& elem : sceneSession->GetToastSession()) {
2446 if (elem != nullptr) {
2447 const auto& persistentId = elem->GetPersistentId();
2448 TLOGI(WmsLogTag::WMS_TOAST, "DestroyToastSession, id: %{public}d", persistentId);
2449 DestroyAndDisconnectSpecificSessionInner(persistentId);
2450 }
2451 }
2452 }
2453
EraseSceneSessionMapById(int32_t persistentId)2454 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
2455 {
2456 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2457 EraseSceneSessionAndMarkDirtyLocked(persistentId);
2458 systemTopSceneSessionMap_.erase(persistentId);
2459 nonSystemFloatSceneSessionMap_.erase(persistentId);
2460 }
2461
2462 /**
2463 * if visible session is erased, mark dirty
2464 * lock-free
2465 */
EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)2466 void SceneSessionManager::EraseSceneSessionAndMarkDirtyLocked(int32_t persistentId)
2467 {
2468 // get scene session lock-free
2469 auto iter = sceneSessionMap_.find(persistentId);
2470 if (iter == sceneSessionMap_.end()) {
2471 TLOGW(WmsLogTag::WMS_MAIN, "id: %{public}d not exist", persistentId);
2472 return;
2473 }
2474 sptr<SceneSession> sceneSession = iter->second;
2475 if (sceneSession != nullptr && sceneSession->IsVisible()) {
2476 sessionMapDirty_ |= static_cast<uint32_t>(SessionUIDirtyFlag::VISIBLE);
2477 }
2478 sceneSessionMap_.erase(persistentId);
2479 }
2480
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,bool needRemoveSession,bool isSaveSnapshot,bool isForceClean)2481 WSError SceneSessionManager::RequestSceneSessionDestruction(const sptr<SceneSession>& sceneSession,
2482 bool needRemoveSession, bool isSaveSnapshot, bool isForceClean)
2483 {
2484 auto task = [this, weakSceneSession = wptr<SceneSession>(sceneSession),
2485 needRemoveSession, isSaveSnapshot, isForceClean]() {
2486 auto scnSession = weakSceneSession.promote();
2487 if (scnSession == nullptr) {
2488 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session is nullptr");
2489 return WSError::WS_ERROR_NULLPTR;
2490 }
2491 auto persistentId = scnSession->GetPersistentId();
2492 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d unfocus", persistentId);
2493 RequestSessionUnfocus(persistentId, FocusChangeReason::SCB_SESSION_REQUEST_UNFOCUS);
2494 lastUpdatedAvoidArea_.erase(persistentId);
2495 DestroyDialogWithMainWindow(scnSession);
2496 DestroyToastSession(scnSession);
2497 DestroySubSession(scnSession); // destroy sub session by destruction
2498 TLOGI(WmsLogTag::WMS_MAIN, "Destruct session id:%{public}d remove:%{public}d isSaveSnapshot:%{public}d"
2499 " isForceClean:%{public}d", persistentId, needRemoveSession, isSaveSnapshot, isForceClean);
2500 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
2501 WindowDestroyNotifyVisibility(scnSession);
2502 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
2503 scnSession->DisconnectTask(false, isSaveSnapshot);
2504 if (!GetSceneSession(persistentId)) {
2505 TLOGE(WmsLogTag::WMS_MAIN, "Destruct session invalid by %{public}d", persistentId);
2506 return WSError::WS_ERROR_INVALID_SESSION;
2507 }
2508 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2509 if (!scnSessionInfo) {
2510 return WSError::WS_ERROR_NULLPTR;
2511 }
2512 scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
2513 ResetSceneSessionInfoWant(scnSessionInfo);
2514 return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession, isForceClean);
2515 };
2516 std::string taskName = "RequestSceneSessionDestruction:PID:" +
2517 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()) : "nullptr");
2518 taskScheduler_->PostAsyncTask(task, taskName);
2519 return WSError::WS_OK;
2520 }
2521
ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo> & sceneSessionInfo)2522 void SceneSessionManager::ResetSceneSessionInfoWant(const sptr<AAFwk::SessionInfo>& sceneSessionInfo)
2523 {
2524 if (sceneSessionInfo->resultCode == -1) {
2525 AAFwk::Want want;
2526 std::string keySessionId = sceneSessionInfo->want.GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2527 want.SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2528 sceneSessionInfo->want = std::move(want);
2529 TLOGI(WmsLogTag::WMS_MAIN, "sceneSessionInfo.resultCode: %{public}d, keySessionId: %{public}s",
2530 sceneSessionInfo->resultCode, keySessionId.c_str());
2531 }
2532 }
2533
ResetWant(sptr<SceneSession> & sceneSession)2534 void SceneSessionManager::ResetWant(sptr<SceneSession>& sceneSession)
2535 {
2536 auto& sessionInfo = sceneSession->GetSessionInfo();
2537 if (sessionInfo.want != nullptr) {
2538 const auto& bundleName = sessionInfo.want->GetElement().GetBundleName();
2539 const auto& abilityName = sessionInfo.want->GetElement().GetAbilityName();
2540 const auto& keySessionId = sessionInfo.want->GetStringParam(ATOMIC_SERVICE_SESSION_ID);
2541 auto want = std::make_shared<AAFwk::Want>();
2542 if (want != nullptr) {
2543 AppExecFwk::ElementName element;
2544 element.SetBundleName(bundleName);
2545 element.SetAbilityName(abilityName);
2546 want->SetElement(element);
2547 want->SetBundle(bundleName);
2548 if (!keySessionId.empty()) {
2549 want->SetParam(ATOMIC_SERVICE_SESSION_ID, keySessionId);
2550 }
2551 sceneSession->SetSessionInfoWant(want);
2552 }
2553 }
2554 }
2555
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession,const bool isForceClean)2556 WSError SceneSessionManager::RequestSceneSessionDestructionInner(sptr<SceneSession>& scnSession,
2557 sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession, const bool isForceClean)
2558 {
2559 auto persistentId = scnSession->GetPersistentId();
2560 TLOGI(WmsLogTag::WMS_MAIN, "begin CloseUIAbility: %{public}d system: %{public}u",
2561 persistentId,
2562 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
2563 if (isForceClean) {
2564 AAFwk::AbilityManagerClient::GetInstance()->CleanUIAbilityBySCB(scnSessionInfo);
2565 } else {
2566 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
2567 }
2568 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
2569 if (needRemoveSession) {
2570 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2571 NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
2572 }
2573 EraseSceneSessionMapById(persistentId);
2574 } else {
2575 // if terminate, reset want. so start from recent, start a new one.
2576 TLOGI(WmsLogTag::WMS_MAIN, "reset want: %{public}d", persistentId);
2577 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
2578 scnSession->SetSessionInfoWant(nullptr);
2579 }
2580 ResetWant(scnSession);
2581 scnSession->ResetSessionInfoResultCode();
2582 }
2583 if (listenerController_ != nullptr) {
2584 NotifySessionForCallback(scnSession, needRemoveSession);
2585 }
2586 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
2587 return WSError::WS_OK;
2588 }
2589
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)2590 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
2591 const sptr<SceneSession>& sceneSession)
2592 {
2593 if (sceneSession == nullptr || sessionStage == nullptr) {
2594 TLOGE(WmsLogTag::WMS_LIFE, "sessionStage(%{public}d) or sceneSession is null", sessionStage == nullptr);
2595 return;
2596 }
2597
2598 auto remoteObject = sessionStage->AsObject();
2599 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
2600 if (windowDeath_ == nullptr) {
2601 TLOGE(WmsLogTag::WMS_LIFE, "failed to create death recipient");
2602 return;
2603 }
2604 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
2605 TLOGE(WmsLogTag::WMS_LIFE, "failed to add death recipient");
2606 return;
2607 }
2608 WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
2609 }
2610
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)2611 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
2612 {
2613 auto task = [this, remoteObject]() {
2614 auto iter = remoteObjectMap_.find(remoteObject);
2615 if (iter == remoteObjectMap_.end()) {
2616 WLOGFE("Invalid remoteObject");
2617 return;
2618 }
2619 WLOGFD("Remote died, id: %{public}d", iter->second);
2620 auto session = GetSceneSession(iter->second);
2621 if (session == nullptr) {
2622 WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
2623 return;
2624 }
2625 DestroyAndDisconnectSpecificSessionInner(iter->second);
2626 };
2627 taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
2628 }
2629
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)2630 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2631 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2632 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
2633 SystemSessionConfig& systemConfig, sptr<IRemoteObject> token)
2634 {
2635 if (property == nullptr) {
2636 WLOGFE("property is nullptr");
2637 return WSError::WS_ERROR_NULLPTR;
2638 }
2639
2640 if (!CheckSystemWindowPermission(property) || !CheckModalSubWindowPermission(property)) {
2641 WLOGFE("create system window or modal subwindow permission denied!");
2642 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2643 }
2644
2645 bool shouldBlock = (property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2646 property->IsFloatingWindowAppType() && shouldHideNonSecureFloatingWindows_.load());
2647 bool isSystemCalling = SessionPermission::IsSystemCalling();
2648 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !isSystemCalling) {
2649 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2650 if (parentSession) {
2651 shouldBlock = (shouldBlock || parentSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag);
2652 }
2653 }
2654 bool isPcWindow = false;
2655 IsPcWindow(isPcWindow);
2656 if (isPcWindow && property->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
2657 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't block");
2658 shouldBlock = false;
2659 }
2660 if (shouldBlock) {
2661 TLOGE(WmsLogTag::WMS_UIEXT, "create non-secure window permission denied!");
2662 return WSError::WS_ERROR_INVALID_OPERATION;
2663 }
2664
2665 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW &&
2666 property->GetExtensionFlag() && property->GetIsUIExtensionAbilityProcess() &&
2667 SessionPermission::IsStartedByUIExtension()) {
2668 auto extensionParentSession = GetSceneSession(property->GetParentPersistentId());
2669 if (extensionParentSession == nullptr) {
2670 WLOGFE("extensionParentSession is invalid with %{public}d", property->GetParentPersistentId());
2671 return WSError::WS_ERROR_NULLPTR;
2672 }
2673 SessionInfo sessionInfo = extensionParentSession->GetSessionInfo();
2674 AAFwk::UIExtensionHostInfo hostInfo;
2675 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionRootHostInfo(token, hostInfo);
2676 if (sessionInfo.bundleName_ != hostInfo.elementName_.GetBundleName()) {
2677 WLOGE("The hostWindow is not this parentwindow ! parentwindow bundleName: %{public}s, "
2678 "hostwindow bundleName: %{public}s", sessionInfo.bundleName_.c_str(),
2679 hostInfo.elementName_.GetBundleName().c_str());
2680 return WSError::WS_ERROR_INVALID_WINDOW;
2681 }
2682 }
2683
2684 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
2685 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
2686 WLOGFE("The alarm window has been deprecated!");
2687 return WSError::WS_ERROR_INVALID_WINDOW;
2688 }
2689
2690 if (property->GetWindowType() == WindowType::WINDOW_TYPE_PIP && !isEnablePiPCreate(property)) {
2691 WLOGFE("pip window is not enable to create.");
2692 return WSError::WS_DO_NOTHING;
2693 }
2694 TLOGI(WmsLogTag::WMS_LIFE, "create specific start, name:%{public}s, type:%{public}d, touchable:%{public}d",
2695 property->GetWindowName().c_str(), property->GetWindowType(), property->GetTouchable());
2696
2697 // Get pid and uid before posting task.
2698 auto pid = IPCSkeleton::GetCallingRealPid();
2699 auto uid = IPCSkeleton::GetCallingUid();
2700 auto task = [this, sessionStage, eventChannel, surfaceNode, property,
2701 &persistentId, &session, &systemConfig, token, pid, uid, isSystemCalling]() {
2702 if (property == nullptr) {
2703 WLOGFE("[WMSSub][WMSSystem] property is nullptr");
2704 return WSError::WS_ERROR_NULLPTR;
2705 }
2706 const auto& type = property->GetWindowType();
2707 // create specific session
2708 SessionInfo info;
2709 info.windowType_ = static_cast<uint32_t>(type);
2710 info.bundleName_ = property->GetSessionInfo().bundleName_;
2711 info.abilityName_ = property->GetSessionInfo().abilityName_;
2712 info.moduleName_ = property->GetSessionInfo().moduleName_;
2713
2714 ClosePipWindowIfExist(type);
2715 sptr<SceneSession> newSession = RequestSceneSession(info, property);
2716 if (newSession == nullptr) {
2717 TLOGE(WmsLogTag::WMS_LIFE, "[WMSSub][WMSSystem] session is nullptr");
2718 return WSError::WS_ERROR_NULLPTR;
2719 }
2720 property->SetSystemCalling(isSystemCalling);
2721 auto errCode = newSession->ConnectInner(
2722 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
2723 newSession->SetIsSystemSpecificSession(isSystemCalling);
2724 systemConfig = systemConfig_;
2725 if (property) {
2726 persistentId = property->GetPersistentId();
2727 }
2728
2729 NotifyCreateSpecificSession(newSession, property, type);
2730 session = newSession;
2731 AddClientDeathRecipient(sessionStage, newSession);
2732 TLOGI(WmsLogTag::WMS_LIFE, "create specific session success, id: %{public}d, "
2733 "parentId: %{public}d, type: %{public}d",
2734 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
2735 return errCode;
2736 };
2737
2738 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
2739 }
2740
ClosePipWindowIfExist(WindowType type)2741 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
2742 {
2743 if (type != WindowType::WINDOW_TYPE_PIP) {
2744 return;
2745 }
2746 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2747 for (const auto& iter: sceneSessionMap_) {
2748 auto& session = iter.second;
2749 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
2750 session->NotifyCloseExistPipWindow();
2751 break;
2752 }
2753 }
2754 }
2755
CheckPiPPriority(const PiPTemplateInfo & pipTemplateInfo)2756 bool SceneSessionManager::CheckPiPPriority(const PiPTemplateInfo& pipTemplateInfo)
2757 {
2758 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2759 for (const auto& iter: sceneSessionMap_) {
2760 auto& session = iter.second;
2761 if (session && session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
2762 pipTemplateInfo.priority < session->GetPiPTemplateInfo().priority &&
2763 session->IsSessionForeground()) {
2764 if (startPiPFailedFunc_) {
2765 startPiPFailedFunc_();
2766 }
2767 TLOGE(WmsLogTag::WMS_PIP, "create pip window failed, reason: low priority.");
2768 return false;
2769 }
2770 }
2771 return true;
2772 }
2773
isEnablePiPCreate(const sptr<WindowSessionProperty> & property)2774 bool SceneSessionManager::isEnablePiPCreate(const sptr<WindowSessionProperty>& property)
2775 {
2776 if (isScreenLocked_) {
2777 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window as screen locked.");
2778 return false;
2779 }
2780 Rect pipRect = property->GetRequestRect();
2781 if (pipRect.width_ == 0 || pipRect.height_ == 0) {
2782 TLOGI(WmsLogTag::WMS_PIP, "pip rect is invalid.");
2783 return false;
2784 }
2785 if (!CheckPiPPriority(property->GetPiPTemplateInfo())) {
2786 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window by priority");
2787 return false;
2788 }
2789 auto parentSession = GetSceneSession(property->GetParentPersistentId());
2790 if (parentSession == nullptr || parentSession->GetSessionState() == SessionState::STATE_DISCONNECT) {
2791 TLOGI(WmsLogTag::WMS_PIP, "skip create pip window, maybe parentSession is null or disconnected");
2792 return false;
2793 }
2794 return true;
2795 }
2796
CheckModalSubWindowPermission(const sptr<WindowSessionProperty> & property)2797 bool SceneSessionManager::CheckModalSubWindowPermission(const sptr<WindowSessionProperty>& property)
2798 {
2799 WindowType type = property->GetWindowType();
2800 if (!WindowHelper::IsSubWindow(type) || !property->IsTopmost()) {
2801 return true;
2802 }
2803
2804 if (!WindowHelper::IsModalSubWindow(type, property->GetWindowFlags())) {
2805 TLOGE(WmsLogTag::WMS_SUB, "Normal subwindow has topmost");
2806 return false;
2807 }
2808
2809 if (!SessionPermission::IsSystemCalling()) {
2810 TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
2811 return false;
2812 }
2813
2814 return true;
2815 }
2816
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)2817 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
2818 {
2819 WindowType type = property->GetWindowType();
2820 if (WindowHelper::IsUIExtensionWindow(type)) {
2821 // UIExtension window disallowed.
2822 return false;
2823 }
2824 if (!WindowHelper::IsSystemWindow(type)) {
2825 // type is not system
2826 return true;
2827 }
2828 if ((type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)
2829 && SessionPermission::IsStartedByInputMethod()) {
2830 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
2831 WLOGFD("check create permission success, input method app create input method window.");
2832 return true;
2833 }
2834 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_PIP) {
2835 // some system types could be created by normal app
2836 return true;
2837 }
2838 if (type == WindowType::WINDOW_TYPE_FLOAT &&
2839 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2840 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
2841 if (systemConfig_.supportTypeFloatWindow_) {
2842 WLOGFD("check create float window permission success on 2in1 device.");
2843 return true;
2844 }
2845 }
2846 if (type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW) {
2847 int32_t parentId = property->GetParentPersistentId();
2848 auto parentSession = GetSceneSession(parentId);
2849 if (parentSession != nullptr && parentSession->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT &&
2850 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
2851 TLOGI(WmsLogTag::WMS_SYSTEM, "check system subWindow permission success, parentId:%{public}d.", parentId);
2852 return true;
2853 } else {
2854 TLOGW(WmsLogTag::WMS_SYSTEM, "check system subWindow permission warning, parentId:%{public}d.", parentId);
2855 }
2856 }
2857 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
2858 TLOGI(WmsLogTag::WMS_SYSTEM, "check create permission success, create with system calling.");
2859 return true;
2860 }
2861 WLOGFE("check system window permission failed.");
2862 return false;
2863 }
2864
RecoverSessionInfo(const sptr<WindowSessionProperty> & property)2865 SessionInfo SceneSessionManager::RecoverSessionInfo(const sptr<WindowSessionProperty>& property)
2866 {
2867 SessionInfo sessionInfo;
2868 if (property == nullptr) {
2869 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2870 return sessionInfo;
2871 }
2872 sessionInfo = property->GetSessionInfo();
2873 sessionInfo.persistentId_ = property->GetPersistentId();
2874 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
2875 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
2876 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
2877 sessionInfo.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN)
2878 ? SessionState::STATE_ACTIVE
2879 : SessionState::STATE_BACKGROUND;
2880 sessionInfo.isPersistentRecover_ = true;
2881 TLOGI(WmsLogTag::WMS_RECOVER,
2882 "Recover and reconnect session with: bundleName=%{public}s, moduleName=%{public}s, "
2883 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
2884 "windowState=%{public}u",
2885 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
2886 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, sessionInfo.sessionState_);
2887 return sessionInfo;
2888 }
2889
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)2890 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
2891 {
2892 TLOGI(WmsLogTag::WMS_RECOVER, "Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
2893 "%{public}d", alivePersistentIds.size(), currentUserId_.load());
2894 alivePersistentIds_ = alivePersistentIds;
2895 }
2896
IsNeedRecover(const int32_t persistentId)2897 bool SceneSessionManager::IsNeedRecover(const int32_t persistentId)
2898 {
2899 auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
2900 if (it == alivePersistentIds_.end()) {
2901 TLOGW(WmsLogTag::WMS_RECOVER, "recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
2902 return false;
2903 }
2904 return true;
2905 }
2906
CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty> & property,bool isSpecificSession)2907 WSError SceneSessionManager::CheckSessionPropertyOnRecovery(const sptr<WindowSessionProperty>& property,
2908 bool isSpecificSession)
2909 {
2910 if (property == nullptr) {
2911 TLOGE(WmsLogTag::WMS_RECOVER, "property is nullptr");
2912 return WSError::WS_ERROR_NULLPTR;
2913 }
2914 if (!CheckSystemWindowPermission(property)) {
2915 TLOGE(WmsLogTag::WMS_RECOVER, "create system window permission denied!");
2916 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2917 }
2918 if (isSpecificSession) {
2919 if (property->GetParentPersistentId() > 0 && !IsNeedRecover(property->GetParentPersistentId())) {
2920 return WSError::WS_ERROR_INVALID_PARAM;
2921 }
2922 } else {
2923 if (!IsNeedRecover(property->GetPersistentId())) {
2924 TLOGE(WmsLogTag::WMS_RECOVER, "no need to recover.");
2925 return WSError::WS_ERROR_INVALID_PARAM;
2926 }
2927 }
2928 return WSError::WS_OK;
2929 }
2930
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)2931 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
2932 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
2933 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
2934 {
2935 auto propCheckRet = CheckSessionPropertyOnRecovery(property, true);
2936 if (propCheckRet != WSError::WS_OK) {
2937 return propCheckRet;
2938 }
2939 auto pid = IPCSkeleton::GetCallingRealPid();
2940 auto uid = IPCSkeleton::GetCallingUid();
2941 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
2942 if (recoveringFinished_) {
2943 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
2944 return WSError::WS_ERROR_INVALID_OPERATION;
2945 }
2946 // recover specific session
2947 SessionInfo info = RecoverSessionInfo(property);
2948 TLOGI(WmsLogTag::WMS_RECOVER, "callingWindowId = %{public}" PRIu32, property->GetCallingSessionId());
2949 ClosePipWindowIfExist(property->GetWindowType());
2950 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
2951 if (sceneSession == nullptr) {
2952 TLOGE(WmsLogTag::WMS_RECOVER, "RequestSceneSession failed");
2953 return WSError::WS_ERROR_NULLPTR;
2954 }
2955
2956 auto persistentId = sceneSession->GetPersistentId();
2957 if (persistentId != info.persistentId_) {
2958 TLOGE(WmsLogTag::WMS_RECOVER,
2959 "SpecificSession PersistentId changed, from %{public}d to %{public}d, parentPersistentId is %{public}d",
2960 info.persistentId_, persistentId, property->GetParentPersistentId());
2961 failRecoveredPersistentIdSet_.insert(property->GetParentPersistentId());
2962 EraseSceneSessionMapById(persistentId);
2963 return WSError::WS_ERROR_INVALID_SESSION;
2964 }
2965
2966 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
2967 if (errCode != WSError::WS_OK) {
2968 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession reconnect failed");
2969 EraseSceneSessionMapById(persistentId);
2970 return errCode;
2971 }
2972 NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType());
2973 CacheSubSessionForRecovering(sceneSession, property);
2974 NotifySessionUnfocusedToClient(persistentId);
2975 AddClientDeathRecipient(sessionStage, sceneSession);
2976 session = sceneSession;
2977 return errCode;
2978 };
2979 return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
2980 }
2981
NotifyRecoveringFinished()2982 void SceneSessionManager::NotifyRecoveringFinished()
2983 {
2984 taskScheduler_->PostAsyncTask([this]() {
2985 TLOGI(WmsLogTag::WMS_RECOVER, "RecoverFinished clear recoverSubSessionCacheMap");
2986 recoveringFinished_ = true;
2987 recoverSubSessionCacheMap_.clear();
2988 }, "NotifyRecoveringFinished");
2989 }
2990
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)2991 void SceneSessionManager::CacheSubSessionForRecovering(
2992 sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
2993 {
2994 if (recoveringFinished_) {
2995 TLOGW(WmsLogTag::WMS_RECOVER, "recovering is finished");
2996 return;
2997 }
2998
2999 if (sceneSession == nullptr || property == nullptr) {
3000 TLOGE(WmsLogTag::WMS_RECOVER, "sceneSession or property is nullptr");
3001 return;
3002 }
3003
3004 auto windowType = property->GetWindowType();
3005 if (!SessionHelper::IsSubWindow(windowType)) {
3006 return;
3007 }
3008
3009 auto persistentId = property->GetParentPersistentId();
3010 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
3011 return;
3012 }
3013
3014 TLOGI(WmsLogTag::WMS_RECOVER,
3015 "Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
3016 sceneSession->GetPersistentId(), persistentId);
3017
3018 if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
3019 recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
3020 } else {
3021 recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
3022 }
3023 }
3024
RecoverCachedSubSession(int32_t persistentId)3025 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
3026 {
3027 auto iter = recoverSubSessionCacheMap_.find(persistentId);
3028 if (iter == recoverSubSessionCacheMap_.end()) {
3029 return;
3030 }
3031
3032 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3033 for (auto& sceneSession : iter->second) {
3034 NotifyCreateSubSession(persistentId, sceneSession);
3035 }
3036 recoverSubSessionCacheMap_.erase(iter);
3037 }
3038
NotifySessionUnfocusedToClient(int32_t persistentId)3039 void SceneSessionManager::NotifySessionUnfocusedToClient(int32_t persistentId)
3040 {
3041 if (listenerController_ != nullptr) {
3042 TLOGI(WmsLogTag::WMS_RECOVER, "persistentId = %{public}" PRId32, persistentId);
3043 listenerController_->NotifySessionUnfocused(persistentId);
3044 }
3045 }
3046
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)3047 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
3048 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
3049 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
3050 {
3051 auto propCheckRet = CheckSessionPropertyOnRecovery(property, false);
3052 if (propCheckRet != WSError::WS_OK) {
3053 return propCheckRet;
3054 }
3055 auto pid = IPCSkeleton::GetCallingRealPid();
3056 auto uid = IPCSkeleton::GetCallingUid();
3057 auto task = [this, sessionStage, eventChannel, surfaceNode, &session, property, token, pid, uid]() {
3058 if (recoveringFinished_) {
3059 TLOGW(WmsLogTag::WMS_RECOVER, "Recover finished, not recovery anymore");
3060 return WSError::WS_ERROR_INVALID_OPERATION;
3061 }
3062 if (recoverSceneSessionFunc_ == nullptr) {
3063 TLOGE(WmsLogTag::WMS_RECOVER, "recoverSceneSessionFunc_ is null");
3064 return WSError::WS_ERROR_NULLPTR;
3065 }
3066 SessionInfo sessionInfo = RecoverSessionInfo(property);
3067 sptr<SceneSession> sceneSession = nullptr;
3068 if (SessionHelper::IsMainWindow(property->GetWindowType())) {
3069 sceneSession = RequestSceneSession(sessionInfo, nullptr);
3070 } else {
3071 sceneSession = RequestSceneSession(sessionInfo, property);
3072 }
3073 if (sceneSession == nullptr) {
3074 TLOGE(WmsLogTag::WMS_RECOVER, "Request sceneSession failed");
3075 return WSError::WS_ERROR_NULLPTR;
3076 }
3077 int32_t persistentId = sceneSession->GetPersistentId();
3078 if (persistentId != sessionInfo.persistentId_) {
3079 TLOGE(WmsLogTag::WMS_RECOVER, "SceneSession PersistentId changed, from %{public}d to %{public}d",
3080 sessionInfo.persistentId_, persistentId);
3081 EraseSceneSessionMapById(persistentId);
3082 return WSError::WS_ERROR_INVALID_SESSION;
3083 }
3084 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
3085 if (ret != WSError::WS_OK) {
3086 TLOGE(WmsLogTag::WMS_RECOVER, "Reconnect failed");
3087 EraseSceneSessionMapById(sessionInfo.persistentId_);
3088 return ret;
3089 }
3090 sceneSession->SetRecovered(true);
3091 recoverSceneSessionFunc_(sceneSession, sessionInfo);
3092 NotifySessionUnfocusedToClient(persistentId);
3093 session = sceneSession;
3094 return WSError::WS_OK;
3095 };
3096 return taskScheduler_->PostSyncTask(task, "RecoverAndReconnectSceneSession");
3097 }
3098
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)3099 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
3100 {
3101 TLOGI(WmsLogTag::WMS_RECOVER, "called");
3102 recoverSceneSessionFunc_ = func;
3103 }
3104
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)3105 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
3106 {
3107 createSystemSessionFunc_ = func;
3108 }
3109
SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc & func)3110 void SceneSessionManager::SetCreateKeyboardSessionListener(const NotifyCreateKeyboardSessionFunc& func)
3111 {
3112 createKeyboardSessionFunc_ = func;
3113 }
3114
SetStartPiPFailedListener(NotifyStartPiPFailedFunc && func)3115 void SceneSessionManager::SetStartPiPFailedListener(NotifyStartPiPFailedFunc&& func)
3116 {
3117 startPiPFailedFunc_ = std::move(func);
3118 }
3119
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)3120 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
3121 const NotifyCreateSubSessionFunc& func)
3122 {
3123 TLOGI(WmsLogTag::WMS_SUB, "RegisterCreateSubSessionListener, id: %{public}d", persistentId);
3124 auto task = [this, persistentId, func]() {
3125 createSubSessionFuncMap_[persistentId] = func;
3126 RecoverCachedSubSession(persistentId);
3127 return WMError::WM_OK;
3128 };
3129 taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
3130 }
3131
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)3132 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
3133 sptr<WindowSessionProperty> property, const WindowType& type)
3134 {
3135 if (newSession == nullptr) {
3136 WLOGFE("newSession is nullptr");
3137 return;
3138 }
3139 if (property == nullptr) {
3140 WLOGFE("property is nullptr");
3141 return;
3142 }
3143 if (SessionHelper::IsSystemWindow(type)) {
3144 if (type == WindowType::WINDOW_TYPE_FLOAT) {
3145 auto parentSession = GetSceneSession(property->GetParentPersistentId());
3146 if (parentSession != nullptr) {
3147 newSession->SetParentSession(parentSession);
3148 }
3149 }
3150 if (type == WindowType::WINDOW_TYPE_TOAST) {
3151 NotifyCreateToastSession(property->GetParentPersistentId(), newSession);
3152 }
3153 if (type != WindowType::WINDOW_TYPE_DIALOG) {
3154 if (WindowHelper::IsSystemSubWindow(type)) {
3155 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3156 } else if (isKeyboardPanelEnabled_ && type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT
3157 && createKeyboardSessionFunc_) {
3158 createKeyboardSessionFunc_(newSession, newSession->GetKeyboardPanelSession());
3159 } else if (createSystemSessionFunc_) {
3160 createSystemSessionFunc_(newSession);
3161 }
3162 TLOGD(WmsLogTag::WMS_LIFE, "Create system session, id:%{public}d, type: %{public}d",
3163 newSession->GetPersistentId(), type);
3164 } else {
3165 TLOGW(WmsLogTag::WMS_LIFE, "Didn't create jsSceneSession for this system type, id:%{public}d, \
3166 type:%{public}d", newSession->GetPersistentId(), type);
3167 return;
3168 }
3169 } else if (SessionHelper::IsSubWindow(type)) {
3170 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
3171 TLOGD(WmsLogTag::WMS_LIFE, "Notify sub jsSceneSession, id:%{public}d, parentId:%{public}d, type:%{public}d",
3172 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
3173 } else {
3174 TLOGW(WmsLogTag::WMS_LIFE, "Invalid session type, id:%{public}d, type:%{public}d",
3175 newSession->GetPersistentId(), type);
3176 }
3177 }
3178
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session,uint32_t windowFlags)3179 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session, uint32_t windowFlags)
3180 {
3181 if (session == nullptr) {
3182 TLOGE(WmsLogTag::WMS_LIFE, "SubSession is nullptr");
3183 return;
3184 }
3185 auto iter = createSubSessionFuncMap_.find(persistentId);
3186 if (iter == createSubSessionFuncMap_.end()) {
3187 TLOGW(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
3188 return;
3189 }
3190
3191 sptr<SceneSession> parentSession = nullptr;
3192 if (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)) {
3193 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3194 parentSession = GetMainParentSceneSession(persistentId, sceneSessionMap_);
3195 } else {
3196 parentSession = GetSceneSession(persistentId);
3197 }
3198 if (parentSession == nullptr) {
3199 TLOGE(WmsLogTag::WMS_LIFE, "Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
3200 persistentId, session->GetPersistentId());
3201 return;
3202 }
3203 parentSession->AddSubSession(session);
3204 session->SetParentSession(parentSession);
3205 if (iter->second) {
3206 iter->second(session);
3207 }
3208 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
3209 persistentId, session->GetPersistentId());
3210 }
3211
GetMainParentSceneSession(int32_t persistentId,const std::map<int32_t,sptr<SceneSession>> & sessionMap)3212 sptr<SceneSession> SceneSessionManager::GetMainParentSceneSession(int32_t persistentId,
3213 const std::map<int32_t, sptr<SceneSession>>& sessionMap)
3214 {
3215 if (persistentId == INVALID_SESSION_ID) {
3216 TLOGW(WmsLogTag::WMS_LIFE, "invalid persistentId id");
3217 return nullptr;
3218 }
3219 auto iter = sessionMap.find(persistentId);
3220 if (iter == sessionMap.end()) {
3221 WLOGFD("Error found scene session with id: %{public}d", persistentId);
3222 return nullptr;
3223 }
3224 sptr<SceneSession> parentSession = iter->second;
3225 if (parentSession == nullptr) {
3226 TLOGW(WmsLogTag::WMS_LIFE, "not find parent session");
3227 return nullptr;
3228 }
3229 bool isNoParentSystemSession = WindowHelper::IsSystemWindow(parentSession->GetWindowType()) &&
3230 parentSession->GetParentPersistentId() == INVALID_SESSION_ID;
3231 if (WindowHelper::IsMainWindow(parentSession->GetWindowType()) || isNoParentSystemSession) {
3232 TLOGD(WmsLogTag::WMS_LIFE, "find main session, id:%{public}u", persistentId);
3233 return parentSession;
3234 }
3235 return GetMainParentSceneSession(parentSession->GetParentPersistentId(), sessionMap);
3236 }
3237
NotifyCreateToastSession(int32_t persistentId,sptr<SceneSession> session)3238 void SceneSessionManager::NotifyCreateToastSession(int32_t persistentId, sptr<SceneSession> session)
3239 {
3240 if (session == nullptr) {
3241 TLOGE(WmsLogTag::WMS_LIFE, "toastSession is nullptr");
3242 return;
3243 }
3244
3245 auto parentSession = GetSceneSession(persistentId);
3246 if (parentSession == nullptr) {
3247 TLOGE(WmsLogTag::WMS_LIFE, "Can't find parentSession, parentId: %{public}d, ToastId: %{public}d",
3248 persistentId, session->GetPersistentId());
3249 return;
3250 }
3251 parentSession->AddToastSession(session);
3252 session->SetParentSession(parentSession);
3253 TLOGD(WmsLogTag::WMS_LIFE, "NotifyCreateToastSession success, parentId: %{public}d, toastId: %{public}d",
3254 persistentId, session->GetPersistentId());
3255 }
3256
UnregisterCreateSubSessionListener(int32_t persistentId)3257 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
3258 {
3259 TLOGI(WmsLogTag::WMS_SUB, "UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
3260 auto task = [this, persistentId]() {
3261 auto iter = createSubSessionFuncMap_.find(persistentId);
3262 if (iter != createSubSessionFuncMap_.end()) {
3263 createSubSessionFuncMap_.erase(persistentId);
3264 } else {
3265 TLOGW(WmsLogTag::WMS_SUB, "Can't find CreateSubSessionListener, id: %{public}d", persistentId);
3266 }
3267 return WMError::WM_OK;
3268 };
3269 taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
3270 }
3271
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)3272 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
3273 {
3274 WLOGFD("SetStatusBarEnabledChangeListener");
3275 if (!func) {
3276 WLOGFD("set func is null");
3277 }
3278 statusBarEnabledChangeFunc_ = func;
3279 }
3280
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)3281 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
3282 const ProcessGestureNavigationEnabledChangeFunc& func)
3283 {
3284 WLOGFD("SetGestureNavigationEnabledChangeListener");
3285 if (!func) {
3286 WLOGFD("set func is null");
3287 }
3288 gestureNavigationEnabledChangeFunc_ = func;
3289 }
3290
OnOutsideDownEvent(int32_t x,int32_t y)3291 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
3292 {
3293 TLOGD(WmsLogTag::WMS_EVENT, "x=%{private}d, y=%{private}d", x, y);
3294 if (outsideDownEventFunc_) {
3295 outsideDownEventFunc_(x, y);
3296 }
3297 }
3298
NotifySessionTouchOutside(int32_t persistentId)3299 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
3300 {
3301 auto task = [this, persistentId]() {
3302 int32_t callingSessionId = INVALID_SESSION_ID;
3303 auto sceneSession = GetSceneSession(persistentId);
3304 if (sceneSession != nullptr && sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
3305 callingSessionId = static_cast<int32_t>(sceneSession->GetCallingSessionId());
3306 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, callingSessionId: %{public}d",
3307 persistentId, callingSessionId);
3308 }
3309 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3310 for (const auto &item : sceneSessionMap_) {
3311 sceneSession = item.second;
3312 if (sceneSession == nullptr) {
3313 continue;
3314 }
3315 if (!(sceneSession->IsVisible() ||
3316 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3317 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
3318 continue;
3319 }
3320 auto sessionId = sceneSession->GetPersistentId();
3321 if (!sceneSession->CheckTouchOutsideCallbackRegistered() &&
3322 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
3323 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
3324 continue;
3325 }
3326 if (sessionId == callingSessionId || sessionId == persistentId) {
3327 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
3328 continue;
3329 }
3330 sceneSession->NotifyTouchOutside();
3331 }
3332 };
3333
3334 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
3335 return;
3336 }
3337
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)3338 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
3339 {
3340 WLOGFD("SetOutsideDownEventListener");
3341 outsideDownEventFunc_ = func;
3342 }
3343
ClearSpecificSessionRemoteObjectMap(int32_t persistentId)3344 void SceneSessionManager::ClearSpecificSessionRemoteObjectMap(int32_t persistentId)
3345 {
3346 for (auto iter = remoteObjectMap_.begin(); iter != remoteObjectMap_.end(); ++iter) {
3347 if (iter->second != persistentId) {
3348 continue;
3349 }
3350 if (windowDeath_ == nullptr) {
3351 TLOGE(WmsLogTag::WMS_LIFE, "death recipient is null");
3352 } else {
3353 if (iter->first == nullptr || !iter->first->RemoveDeathRecipient(windowDeath_)) {
3354 TLOGE(WmsLogTag::WMS_LIFE, "failed to remove death recipient");
3355 }
3356 }
3357 remoteObjectMap_.erase(iter);
3358 break;
3359 }
3360 }
3361
DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)3362 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(const int32_t persistentId)
3363 {
3364 auto sceneSession = GetSceneSession(persistentId);
3365 if (sceneSession == nullptr) {
3366 return WSError::WS_ERROR_NULLPTR;
3367 }
3368 auto ret = sceneSession->UpdateActiveStatus(false);
3369 WindowDestroyNotifyVisibility(sceneSession);
3370 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
3371 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3372 if (parentSession == nullptr) {
3373 TLOGE(WmsLogTag::WMS_DIALOG, "Dialog not bind parent");
3374 } else {
3375 parentSession->RemoveDialogToParentSession(sceneSession);
3376 }
3377 }
3378 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_TOAST) {
3379 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3380 if (parentSession != nullptr) {
3381 TLOGD(WmsLogTag::WMS_TOAST, "Find parentSession, id: %{public}d", persistentId);
3382 parentSession->RemoveToastSession(persistentId);
3383 } else {
3384 TLOGW(WmsLogTag::WMS_TOAST, "ParentSession is nullptr, id: %{public}d", persistentId);
3385 }
3386 }
3387 ret = sceneSession->Disconnect();
3388 sceneSession->ClearSpecificSessionCbMap();
3389 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
3390 DestroySubSession(sceneSession);
3391 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
3392 if (parentSession != nullptr) {
3393 TLOGD(WmsLogTag::WMS_SUB, "Find parentSession, id: %{public}d", persistentId);
3394 parentSession->RemoveSubSession(sceneSession->GetPersistentId());
3395 } else {
3396 TLOGW(WmsLogTag::WMS_SUB, "ParentSession is nullptr, id: %{public}d", persistentId);
3397 }
3398 DestroyUIServiceExtensionSubWindow(sceneSession);
3399 }
3400 {
3401 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3402 EraseSceneSessionAndMarkDirtyLocked(persistentId);
3403 systemTopSceneSessionMap_.erase(persistentId);
3404 nonSystemFloatSceneSessionMap_.erase(persistentId);
3405 UnregisterCreateSubSessionListener(persistentId);
3406 }
3407 ClearSpecificSessionRemoteObjectMap(persistentId);
3408 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session end, id: %{public}d", persistentId);
3409 return ret;
3410 }
3411
DestroyUIServiceExtensionSubWindow(const sptr<SceneSession> & sceneSession)3412 void SceneSessionManager::DestroyUIServiceExtensionSubWindow(const sptr<SceneSession>& sceneSession)
3413 {
3414 if (!sceneSession) {
3415 TLOGE(WmsLogTag::WMS_SUB,"sceneSession is null");
3416 return;
3417 }
3418 auto sessionProperty = sceneSession->GetSessionProperty();
3419 if (sessionProperty && sessionProperty->GetExtensionFlag() == true &&
3420 !sessionProperty->GetIsUIExtensionAbilityProcess()) {
3421 sceneSession->NotifyDestroy();
3422 int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->
3423 TerminateUIServiceExtensionAbility(sceneSession->GetAbilityToken());
3424 TLOGI(WmsLogTag::WMS_SUB,"TerminateUIServiceExtensionAbility id:%{public}d errCode:%{public}d",
3425 sceneSession->GetPersistentId(), errCode);
3426 }
3427 }
3428
DestroyAndDisconnectSpecificSession(const int32_t persistentId)3429 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t persistentId)
3430 {
3431 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3432 auto task = [this, persistentId, callingPid]() {
3433 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3434 auto sceneSession = GetSceneSession(persistentId);
3435 if (sceneSession == nullptr) {
3436 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3437 return WSError::WS_ERROR_NULLPTR;
3438 }
3439
3440 if (callingPid != sceneSession->GetCallingPid()) {
3441 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3442 return WSError::WS_ERROR_INVALID_PERMISSION;
3443 }
3444 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3445 };
3446
3447 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3448 }
3449
DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,const sptr<IRemoteObject> & callback)3450 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionWithDetachCallback(const int32_t persistentId,
3451 const sptr<IRemoteObject>& callback)
3452 {
3453 if (callback == nullptr) {
3454 return WSError::WS_ERROR_NULLPTR;
3455 }
3456 const auto callingPid = IPCSkeleton::GetCallingRealPid();
3457 auto task = [this, persistentId, callingPid, callback]() {
3458 TLOGI(WmsLogTag::WMS_LIFE, "Destroy specific session start, id: %{public}d", persistentId);
3459 auto sceneSession = GetSceneSession(persistentId);
3460 if (sceneSession == nullptr) {
3461 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr, persistentId:%{public}d", persistentId);
3462 return WSError::WS_ERROR_NULLPTR;
3463 }
3464
3465 if (callingPid != sceneSession->GetCallingPid()) {
3466 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, not destroy by the same process");
3467 return WSError::WS_ERROR_INVALID_PERMISSION;
3468 }
3469 sceneSession->RegisterDetachCallback(iface_cast<IPatternDetachCallback>(callback));
3470 return DestroyAndDisconnectSpecificSessionInner(persistentId);
3471 };
3472
3473 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
3474 }
3475
GetWindowSceneConfig() const3476 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
3477 {
3478 return appWindowSceneConfig_;
3479 }
3480
UpdateRotateAnimationConfig(const RotateAnimationConfig & config)3481 void SceneSessionManager::UpdateRotateAnimationConfig(const RotateAnimationConfig& config)
3482 {
3483 auto task = [this, config]() {
3484 TLOGI(WmsLogTag::DEFAULT, "update rotate animation config duration: %{public}d", config.duration_);
3485 rotateAnimationConfig_.duration_ = config.duration_;
3486 };
3487 taskScheduler_->PostAsyncTask(task, "UpdateRotateAnimationConfig");
3488 }
3489
ProcessBackEvent()3490 WSError SceneSessionManager::ProcessBackEvent()
3491 {
3492 auto task = [this]() {
3493 auto session = GetSceneSession(focusedSessionId_);
3494 if (!session) {
3495 TLOGNE(WmsLogTag::WMS_MAIN, "session is nullptr: %{public}d", focusedSessionId_);
3496 return WSError::WS_ERROR_INVALID_SESSION;
3497 }
3498 TLOGNI(WmsLogTag::WMS_MAIN, "ProcessBackEvent session persistentId:%{public}d needBlock:%{public}d",
3499 focusedSessionId_, needBlockNotifyFocusStatusUntilForeground_);
3500 if (needBlockNotifyFocusStatusUntilForeground_) {
3501 TLOGND(WmsLogTag::WMS_MAIN, "RequestSessionBack when start session");
3502 if (session->GetSessionInfo().abilityInfo != nullptr &&
3503 session->GetSessionInfo().abilityInfo->unclearableMission) {
3504 TLOGNI(WmsLogTag::WMS_MAIN, "backPress unclearableMission");
3505 return WSError::WS_OK;
3506 }
3507 session->RequestSessionBack(true);
3508 return WSError::WS_OK;
3509 }
3510 if (session->GetSessionInfo().isSystem_ && rootSceneProcessBackEventFunc_) {
3511 rootSceneProcessBackEventFunc_();
3512 } else {
3513 session->ProcessBackEvent();
3514 }
3515 return WSError::WS_OK;
3516 };
3517
3518 taskScheduler_->PostAsyncTask(task, __func__);
3519 return WSError::WS_OK;
3520 }
3521
InitUserInfo(int32_t userId,std::string & fileDir)3522 WSError SceneSessionManager::InitUserInfo(int32_t userId, std::string& fileDir)
3523 {
3524 if (userId == DEFAULT_USERID || fileDir.empty()) {
3525 TLOGE(WmsLogTag::WMS_MAIN, "params invalid");
3526 return WSError::WS_DO_NOTHING;
3527 }
3528 TLOGI(WmsLogTag::WMS_MAIN, "userId : %{public}d, path : %{public}s", userId, fileDir.c_str());
3529 auto task = [this, userId, &fileDir]() {
3530 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
3531 TLOGD(WmsLogTag::WMS_MAIN, "Create snapshot directory failed");
3532 }
3533 if (!ScenePersistence::CreateUpdatedIconDir(fileDir)) {
3534 TLOGD(WmsLogTag::WMS_MAIN, "Create icon directory failed");
3535 }
3536 currentUserId_ = userId;
3537 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3538 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3539 RegisterSecSurfaceInfoListener();
3540 return WSError::WS_OK;
3541 };
3542 return taskScheduler_->PostSyncTask(task, "InitUserInfo");
3543 }
3544
NotifySwitchingUser(const bool isUserActive)3545 void SceneSessionManager::NotifySwitchingUser(const bool isUserActive)
3546 {
3547 auto task = [this, isUserActive]() {
3548 TLOGI(WmsLogTag::WMS_MULTI_USER, "Notify switching user. IsUserActive=%{public}u, currentUserId=%{public}d",
3549 isUserActive, currentUserId_.load());
3550 isUserBackground_ = !isUserActive;
3551 SceneInputManager::GetInstance().SetUserBackground(!isUserActive);
3552 if (isUserActive) { // switch to current user
3553 SceneInputManager::GetInstance().SetCurrentUserId(currentUserId_);
3554 AbilityInfoManager::GetInstance().SetCurrentUserId(currentUserId_);
3555 // notify screenSessionManager to recover current user
3556 ScreenSessionManagerClient::GetInstance().SwitchingCurrentUser();
3557 FlushWindowInfoToMMI(true);
3558 NotifyAllAccessibilityInfo();
3559 rsInterface_.AddVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3560 UpdatePrivateStateAndNotifyForAllScreens();
3561 } else { // switch to another user
3562 SceneInputManager::GetInstance().FlushEmptyInfoToMMI();
3563 rsInterface_.RemoveVirtualScreenBlackList(INVALID_SCREEN_ID, skipSurfaceNodeIds_);
3564 }
3565 return WSError::WS_OK;
3566 };
3567 taskScheduler_->PostSyncTask(task, "NotifySwitchingUser");
3568 }
3569
GetBundleManager()3570 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
3571 {
3572 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3573 if (systemAbilityMgr == nullptr) {
3574 WLOGFE("Failed to get SystemAbilityManager.");
3575 return nullptr;
3576 }
3577
3578 auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3579 if (bmsObj == nullptr) {
3580 WLOGFE("Failed to get BundleManagerService.");
3581 return nullptr;
3582 }
3583
3584 return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
3585 }
3586
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)3587 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
3588 const AppExecFwk::AbilityInfo& abilityInfo)
3589 {
3590 auto context = rootSceneContextWeak_.lock();
3591 if (!context) {
3592 WLOGFE("context is nullptr.");
3593 return nullptr;
3594 }
3595 auto resourceMgr = context->GetResourceManager();
3596 if (!resourceMgr) {
3597 WLOGFE("resourceMgr is nullptr.");
3598 return nullptr;
3599 }
3600 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
3601 if (!resConfig) {
3602 WLOGFE("resConfig is nullptr.");
3603 return nullptr;
3604 }
3605 resourceMgr->GetResConfig(*resConfig);
3606 resourceMgr = Global::Resource::CreateResourceManager(
3607 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
3608 if (!resourceMgr) {
3609 WLOGFE("resourceMgr is nullptr.");
3610 return nullptr;
3611 }
3612 resourceMgr->UpdateResConfig(*resConfig);
3613
3614 std::string loadPath;
3615 if (!abilityInfo.hapPath.empty()) { // zipped hap
3616 loadPath = abilityInfo.hapPath;
3617 } else {
3618 loadPath = abilityInfo.resourcePath;
3619 }
3620
3621 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_COLOR | Global::Resource::SELECT_MEDIA)) {
3622 WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
3623 }
3624 return resourceMgr;
3625 }
3626
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)3627 bool SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
3628 std::string& path, uint32_t& bgColor)
3629 {
3630 auto resourceMgr = GetResourceManager(abilityInfo);
3631 if (!resourceMgr) {
3632 WLOGFE("resourceMgr is nullptr.");
3633 return false;
3634 }
3635
3636 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
3637 WLOGFE("Failed to get background color, id %{public}d.", abilityInfo.startWindowBackgroundId);
3638 return false;
3639 }
3640
3641 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
3642 WLOGFE("Failed to get icon, id %{public}d.", abilityInfo.startWindowIconId);
3643 return false;
3644 }
3645
3646 if (!abilityInfo.hapPath.empty()) { // zipped hap
3647 auto pos = path.find_last_of('.');
3648 if (pos == std::string::npos) {
3649 WLOGFE("Format error, path %{private}s.", path.c_str());
3650 return false;
3651 }
3652 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
3653 }
3654 return true;
3655 }
3656
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3657 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3658 {
3659 if (!bundleMgr_) {
3660 WLOGFE("bundleMgr_ is nullptr.");
3661 return;
3662 }
3663 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
3664 if (GetStartingWindowInfoFromCache(sessionInfo, path, bgColor)) {
3665 WLOGFI("Found in cache: %{public}s, %{public}x", path.c_str(), bgColor);
3666 return;
3667 }
3668 AAFwk::Want want;
3669 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3670 AppExecFwk::AbilityInfo abilityInfo;
3671 if (!bundleMgr_->QueryAbilityInfo(
3672 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
3673 WLOGFE("Get ability info from BMS failed!");
3674 return;
3675 }
3676
3677 if (GetStartupPageFromResource(abilityInfo, path, bgColor)) {
3678 CacheStartingWindowInfo(abilityInfo, path, bgColor);
3679 }
3680 WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
3681 abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
3682 }
3683
GetStartingWindowInfoFromCache(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)3684 bool SceneSessionManager::GetStartingWindowInfoFromCache(
3685 const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
3686 {
3687 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartingWindowInfoFromCache");
3688 std::shared_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3689 auto iter = startingWindowMap_.find(sessionInfo.bundleName_);
3690 if (iter == startingWindowMap_.end()) {
3691 return false;
3692 }
3693 auto key = sessionInfo.moduleName_ + sessionInfo.abilityName_;
3694 const auto& infoMap = iter->second;
3695 auto infoMapIter = infoMap.find(key);
3696 if (infoMapIter == infoMap.end()) {
3697 return false;
3698 }
3699 path = infoMapIter->second.startingWindowIconPath_;
3700 bgColor = infoMapIter->second.startingWindowBackgroundColor_;
3701 return true;
3702 }
3703
CacheStartingWindowInfo(const AppExecFwk::AbilityInfo & abilityInfo,const std::string & path,const uint32_t & bgColor)3704 void SceneSessionManager::CacheStartingWindowInfo(
3705 const AppExecFwk::AbilityInfo& abilityInfo, const std::string& path, const uint32_t& bgColor)
3706 {
3707 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:CacheStartingWindowInfo");
3708 auto key = abilityInfo.moduleName + abilityInfo.name;
3709 StartingWindowInfo info = {
3710 .startingWindowBackgroundId_ = abilityInfo.startWindowBackgroundId,
3711 .startingWindowIconId_ = abilityInfo.startWindowIconId,
3712 .startingWindowBackgroundColor_ = bgColor,
3713 .startingWindowIconPath_ = path,
3714 };
3715 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3716 auto iter = startingWindowMap_.find(abilityInfo.bundleName);
3717 if (iter != startingWindowMap_.end()) {
3718 auto& infoMap = iter->second;
3719 infoMap.emplace(key, info);
3720 return;
3721 }
3722 if (startingWindowMap_.size() >= MAX_CACHE_COUNT) {
3723 startingWindowMap_.erase(startingWindowMap_.begin());
3724 }
3725 std::map<std::string, StartingWindowInfo> infoMap({{ key, info }});
3726 startingWindowMap_.emplace(abilityInfo.bundleName, infoMap);
3727 }
3728
OnBundleUpdated(const std::string & bundleName,int userId)3729 void SceneSessionManager::OnBundleUpdated(const std::string& bundleName, int userId)
3730 {
3731 taskScheduler_->PostAsyncTask([this, bundleName]() {
3732 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3733 auto iter = startingWindowMap_.find(bundleName);
3734 if (iter != startingWindowMap_.end()) {
3735 startingWindowMap_.erase(iter);
3736 }
3737 },
3738 "OnBundleUpdated");
3739 }
3740
OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration> & configuration)3741 void SceneSessionManager::OnConfigurationUpdated(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
3742 {
3743 taskScheduler_->PostAsyncTask([this]() {
3744 std::unique_lock<std::shared_mutex> lock(startingWindowMapMutex_);
3745 startingWindowMap_.clear();
3746 },
3747 "OnConfigurationUpdated");
3748 }
3749
FillSessionInfo(sptr<SceneSession> & sceneSession)3750 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
3751 {
3752 auto sessionInfo = sceneSession->GetSessionInfo();
3753 if (sessionInfo.bundleName_.empty()) {
3754 WLOGFE("bundleName_ is empty");
3755 return;
3756 }
3757 if (sessionInfo.isSystem_) {
3758 WLOGFD("is system scene!");
3759 return;
3760 }
3761 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
3762 sessionInfo.moduleName_);
3763 if (abilityInfo == nullptr) {
3764 WLOGFE("abilityInfo is nullptr!");
3765 return;
3766 }
3767 sceneSession->SetEnableRemoveStartingWindow(GetEnableRemoveStartingWindowFromBMS(abilityInfo));
3768 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
3769 sceneSession->SetSessionInfoTime(GetCurrentTime());
3770 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3771 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3772 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3773 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3774 }
3775 TLOGI(WmsLogTag::DEFAULT, "bundleName:%{public}s removeMissionAfterTerminate:%{public}d "
3776 "excludeFromMissions:%{public}d label:%{public}s iconPath:%{public}s collaboratorType:%{public}s.",
3777 abilityInfo->bundleName.c_str(), abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
3778 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
3779 }
3780
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)3781 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3782 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
3783 {
3784 if (!bundleMgr_) {
3785 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
3786 return nullptr;
3787 }
3788 AAFwk::Want want;
3789 want.SetElementName("", bundleName, abilityName, moduleName);
3790 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3791 if (abilityInfo == nullptr) {
3792 WLOGFE("abilityInfo is nullptr!");
3793 return nullptr;
3794 }
3795 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3796 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3797 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3798 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
3799 if (!ret) {
3800 WLOGFE("Get ability info from BMS failed!");
3801 return nullptr;
3802 }
3803 return abilityInfo;
3804 }
3805
GetTopWindowByTraverseSessionTree(const sptr<SceneSession> & session,uint32_t & topWinId,uint32_t & zOrder)3806 static void GetTopWindowByTraverseSessionTree(const sptr<SceneSession>& session,
3807 uint32_t& topWinId, uint32_t& zOrder)
3808 {
3809 const auto& subVec = session->GetSubSession();
3810 for (const auto& subSession : subVec) {
3811 if (subSession == nullptr || subSession->GetCallingPid() != session->GetCallingPid()) {
3812 TLOGW(WmsLogTag::WMS_SUB,
3813 "subSession is null or subWin's callingPid is not equal to mainWin's callingPid");
3814 continue;
3815 }
3816 if ((subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
3817 subSession->GetSessionState() == SessionState::STATE_ACTIVE) &&
3818 subSession->GetZOrder() > zOrder) {
3819 topWinId = static_cast<uint32_t>(subSession->GetPersistentId());
3820 zOrder = subSession->GetZOrder();
3821 TLOGD(WmsLogTag::WMS_SUB, "Current zorder is larger than mainWin, mainId: %{public}d, "
3822 "topWinId: %{public}d, zOrder: %{public}d", session->GetPersistentId(), topWinId, zOrder);
3823 }
3824 if (subSession->GetSubSession().size() > 0) {
3825 GetTopWindowByTraverseSessionTree(subSession, topWinId, zOrder);
3826 }
3827 }
3828 }
3829
3830 /** @note @window.hierarchy */
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)3831 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
3832 {
3833 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
3834 auto task = [this, mainWinId, &topWinId, callingPid]() {
3835 const auto& mainSession = GetSceneSession(mainWinId);
3836 if (mainSession == nullptr) {
3837 return WMError::WM_ERROR_INVALID_WINDOW;
3838 }
3839
3840 if (callingPid != mainSession->GetCallingPid()) {
3841 WLOGFE("Permission denied, not destroy by the same process");
3842 return WMError::WM_ERROR_INVALID_PERMISSION;
3843 }
3844 uint32_t zOrder = mainSession->GetZOrder();
3845 topWinId = mainWinId;
3846 GetTopWindowByTraverseSessionTree(mainSession, topWinId, zOrder);
3847 TLOGI(WmsLogTag::WMS_SUB, "[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, "
3848 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
3849 return WMError::WM_OK;
3850 };
3851
3852 if (!Session::IsScbCoreEnabled()) {
3853 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3854 }
3855 bool postNow = false;
3856 auto mainSession = GetSceneSession(mainWinId);
3857 if (mainSession != nullptr) {
3858 postNow = !(mainSession->GetUIStateDirty());
3859 }
3860 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
3861 if (postNow || (mainEventRunner && mainEventRunner->IsCurrentRunnerThread()) ||
3862 taskScheduler_->GetEventHandler()->GetEventRunner()->IsCurrentRunnerThread()) {
3863 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3864 }
3865 TLOGI(WmsLogTag::WMS_PIPELINE, "wait for flush UI, id: %{public}d", mainWinId);
3866 {
3867 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
3868 if (nextFlushCompletedCV_.wait_for(lock, std::chrono::milliseconds(GET_TOP_WINDOW_DELAY)) ==
3869 std::cv_status::timeout) {
3870 TLOGW(WmsLogTag::WMS_PIPELINE, "wait for 100ms");
3871 }
3872 }
3873 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
3874 }
3875
GetParentMainWindowIdInner(const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap,int32_t windowId,int32_t & mainWindowId)3876 static WMError GetParentMainWindowIdInner(const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap,
3877 int32_t windowId, int32_t& mainWindowId)
3878 {
3879 auto iter = sceneSessionMap.find(windowId);
3880 if (iter == sceneSessionMap.end()) {
3881 TLOGD(WmsLogTag::WMS_SUB, "not found scene session with id: %{public}d", windowId);
3882 return WMError::WM_ERROR_NULLPTR;
3883 }
3884 sptr<SceneSession> sceneSession = iter->second;
3885 if (sceneSession == nullptr) {
3886 TLOGW(WmsLogTag::WMS_SUB, "not find parent session");
3887 return WMError::WM_ERROR_NULLPTR;
3888 }
3889 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
3890 mainWindowId = sceneSession->GetPersistentId();
3891 return WMError::WM_OK;
3892 }
3893 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3894 WindowHelper::IsDialogWindow(sceneSession->GetWindowType())) {
3895 return GetParentMainWindowIdInner(sceneSessionMap, sceneSession->GetParentPersistentId(), mainWindowId);
3896 }
3897 // not sub window, dialog, return invalid id
3898 mainWindowId = INVALID_SESSION_ID;
3899 return WMError::WM_OK;
3900 }
3901
GetParentMainWindowId(int32_t windowId,int32_t & mainWindowId)3902 WMError SceneSessionManager::GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId)
3903 {
3904 if (windowId == INVALID_SESSION_ID) {
3905 TLOGW(WmsLogTag::WMS_SUB, "invalid windowId id");
3906 return WMError::WM_ERROR_INVALID_PARAM;
3907 }
3908 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3909 return GetParentMainWindowIdInner(sceneSessionMap_, windowId, mainWindowId);
3910 }
3911
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3912 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
3913 const sptr<SceneSession>& sceneSession)
3914 {
3915 auto systemBarProperties = property->GetSystemBarProperty();
3916 for (auto iter : systemBarProperties) {
3917 if (iter.first == type) {
3918 sceneSession->SetSystemBarProperty(iter.first, iter.second);
3919 TLOGD(WmsLogTag::WMS_IMMS, "SetSystemBarProperty: %{public}d, enable: %{public}d",
3920 static_cast<int32_t>(iter.first), iter.second.enable_);
3921 }
3922 }
3923 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
3924 }
3925
3926 /** @note @window.hierarchy */
UpdateTopmostProperty(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3927 WMError SceneSessionManager::UpdateTopmostProperty(const sptr<WindowSessionProperty>& property,
3928 const sptr<SceneSession>& sceneSession)
3929 {
3930 if (!SessionPermission::IsSystemCalling()) {
3931 TLOGE(WmsLogTag::WMS_LAYOUT, "UpdateTopmostProperty permission denied!");
3932 return WMError::WM_ERROR_NOT_SYSTEM_APP;
3933 }
3934
3935 sceneSession->SetTopmost(property->IsTopmost());
3936 return WMError::WM_OK;
3937 }
3938
HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)3939 void SceneSessionManager::HandleHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
3940 const sptr<SceneSession>& sceneSession)
3941 {
3942 bool isPcWindow = false;
3943 IsPcWindow(isPcWindow);
3944 if (isPcWindow) {
3945 TLOGI(WmsLogTag::WMS_UIEXT, "PC window don't hide");
3946 return;
3947 }
3948 auto propertyOld = sceneSession->GetSessionProperty();
3949 if (propertyOld == nullptr) {
3950 TLOGI(WmsLogTag::DEFAULT, "session property null");
3951 return;
3952 }
3953
3954 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
3955 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
3956 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
3957 TLOGI(WmsLogTag::DEFAULT, "property hideNonSystemFloatingWindows not change");
3958 return;
3959 }
3960
3961 if (IsSessionVisibleForeground(sceneSession)) {
3962 if (hideNonSystemFloatingWindowsOld) {
3963 UpdateForceHideState(sceneSession, propertyOld, false);
3964 } else {
3965 UpdateForceHideState(sceneSession, property, true);
3966 }
3967 }
3968 }
3969
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)3970 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
3971 const sptr<WindowSessionProperty>& property, bool add)
3972 {
3973 if (systemConfig_.uiType_ == UI_TYPE_PC) {
3974 TLOGI(WmsLogTag::DEFAULT, "IsPcWindow, ineffective");
3975 return;
3976 }
3977 if (property == nullptr) {
3978 WLOGFD("property is nullptr");
3979 return;
3980 }
3981 auto persistentId = sceneSession->GetPersistentId();
3982 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
3983 bool notifyAll = false;
3984 if (add) {
3985 if (property->GetHideNonSystemFloatingWindows()) {
3986 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
3987 notifyAll = !forceHideFloatOld;
3988 } else if (property->IsFloatingWindowAppType()) {
3989 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
3990 if (forceHideFloatOld) {
3991 sceneSession->NotifyForceHideChange(true);
3992 }
3993 }
3994 } else {
3995 if (property->GetHideNonSystemFloatingWindows()) {
3996 systemTopSceneSessionMap_.erase(persistentId);
3997 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
3998 } else if (property->IsFloatingWindowAppType()) {
3999 nonSystemFloatSceneSessionMap_.erase(persistentId);
4000 if (property->GetForceHide()) {
4001 sceneSession->NotifyForceHideChange(false);
4002 }
4003 }
4004 }
4005 if (notifyAll) {
4006 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
4007 for (const auto& item : nonSystemFloatSceneSessionMap_) {
4008 auto forceHideSceneSession = item.second;
4009 auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
4010 if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
4011 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
4012 }
4013 }
4014 }
4015 }
4016
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)4017 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
4018 {
4019 #ifdef POWER_MANAGER_ENABLE
4020 auto task = [this, sceneSession]() {
4021 if (sceneSession == nullptr) {
4022 WLOGFE("session is invalid");
4023 return;
4024 }
4025 WLOGFD("Win: %{public}s, is turn on%{public}d",
4026 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
4027 std::string identity = IPCSkeleton::ResetCallingIdentity();
4028 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
4029 WLOGI("turn screen on");
4030 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
4031 }
4032 // set ipc identity to raw
4033 IPCSkeleton::SetCallingIdentity(identity);
4034 };
4035 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
4036
4037 #else
4038 WLOGFD("Can not found the sub system of PowerMgr");
4039 #endif
4040 }
4041
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)4042 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
4043 {
4044 #ifdef POWER_MANAGER_ENABLE
4045 wptr<SceneSession> weakSceneSession(sceneSession);
4046 auto task = [this, weakSceneSession, requireLock]() {
4047 auto scnSession = weakSceneSession.promote();
4048 if (scnSession == nullptr) {
4049 WLOGFE("session is invalid");
4050 return;
4051 }
4052 if (requireLock && scnSession->keepScreenLock_ == nullptr) {
4053 // reset ipc identity
4054 std::string identity = IPCSkeleton::ResetCallingIdentity();
4055 scnSession->keepScreenLock_ =
4056 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
4057 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
4058 // set ipc identity to raw
4059 IPCSkeleton::SetCallingIdentity(identity);
4060 }
4061 if (scnSession->keepScreenLock_ == nullptr) {
4062 return;
4063 }
4064 bool shouldLock = requireLock && IsSessionVisibleForeground(scnSession);
4065 TLOGNI(WmsLogTag::DEFAULT, "keep screen on: [%{public}s, %{public}d, %{public}d, %{public}d, %{public}d]",
4066 scnSession->GetWindowName().c_str(), scnSession->GetSessionState(),
4067 scnSession->IsVisible(), requireLock, shouldLock);
4068 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
4069 ErrCode res;
4070 std::string identity = IPCSkeleton::ResetCallingIdentity();
4071 if (shouldLock) {
4072 res = scnSession->keepScreenLock_->Lock();
4073 } else {
4074 res = scnSession->keepScreenLock_->UnLock();
4075 }
4076 // set ipc identity to raw
4077 IPCSkeleton::SetCallingIdentity(identity);
4078 if (res != ERR_OK) {
4079 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
4080 requireLock, res);
4081 }
4082 };
4083 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
4084 #else
4085 WLOGFD("Can not found the sub system of PowerMgr");
4086 #endif
4087 }
4088
NotifyVisibleChange(int32_t persistentId)4089 bool SceneSessionManager::NotifyVisibleChange(int32_t persistentId)
4090 {
4091 auto sceneSession = GetSceneSession(persistentId);
4092 if (sceneSession == nullptr) {
4093 return false;
4094 }
4095 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
4096 ProcessWindowModeType();
4097 return true;
4098 }
4099
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)4100 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
4101 {
4102 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
4103 if (GetDisplayBrightness() != brightness &&
4104 GetFocusedSessionId() == sceneSession->GetPersistentId()) {
4105 PostBrightnessTask(brightness);
4106 }
4107 #else
4108 WLOGFD("Can not found the sub system of DisplayPowerMgr");
4109 #endif
4110 brightnessSessionId_ = sceneSession->GetPersistentId();
4111 return WSError::WS_OK;
4112 }
4113
PostBrightnessTask(float brightness)4114 void SceneSessionManager::PostBrightnessTask(float brightness)
4115 {
4116 bool postTaskRet = true;
4117 bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4118 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4119 if (!isPC) {
4120 auto task = [] {
4121 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4122 };
4123 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:RestoreBrightness", 0);
4124 }
4125 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4126 } else {
4127 auto task = [brightness, isPC] {
4128 if (isPC) {
4129 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4130 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4131 } else {
4132 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4133 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4134 }
4135 };
4136 postTaskRet = eventHandler_->PostTask(task, "DisplayPowerMgr:OverrideBrightness", 0);
4137 SetDisplayBrightness(brightness);
4138 }
4139 if (!postTaskRet) {
4140 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "post task failed. task is SetBrightness");
4141 }
4142 }
4143
UpdateBrightness(int32_t persistentId)4144 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
4145 {
4146 auto sceneSession = GetSceneSession(persistentId);
4147 if (sceneSession == nullptr) {
4148 TLOGE(WmsLogTag::WMS_ATTRIBUTE, "session is invalid");
4149 return WSError::WS_ERROR_NULLPTR;
4150 }
4151 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
4152 sceneSession->GetSessionInfo().isSystem_)) {
4153 TLOGW(WmsLogTag::WMS_ATTRIBUTE, "only app main window can set brightness");
4154 return WSError::WS_DO_NOTHING;
4155 }
4156 auto brightness = sceneSession->GetBrightness();
4157 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
4158 bool isPC = systemConfig_.uiType_ == UI_TYPE_PC;
4159 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
4160 if (GetDisplayBrightness() != brightness) {
4161 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with default value");
4162 if (!isPC) {
4163 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
4164 }
4165 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
4166 }
4167 brightnessSessionId_ = INVALID_WINDOW_ID;
4168 } else {
4169 if (GetDisplayBrightness() != brightness) {
4170 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "adjust brightness with value");
4171 if (isPC) {
4172 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().SetBrightness(
4173 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4174 } else {
4175 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
4176 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
4177 }
4178 SetDisplayBrightness(brightness);
4179 }
4180 brightnessSessionId_ = sceneSession->GetPersistentId();
4181 }
4182 return WSError::WS_OK;
4183 }
4184
GetCurrentUserId() const4185 int32_t SceneSessionManager::GetCurrentUserId() const
4186 {
4187 return currentUserId_;
4188 }
4189
SetDisplayBrightness(float brightness)4190 void SceneSessionManager::SetDisplayBrightness(float brightness)
4191 {
4192 displayBrightness_ = brightness;
4193 }
4194
GetDisplayBrightness() const4195 float SceneSessionManager::GetDisplayBrightness() const
4196 {
4197 return displayBrightness_;
4198 }
4199
SetGestureNavigaionEnabled(bool enable)4200 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
4201 {
4202 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
4203 TLOGE(WmsLogTag::WMS_EVENT, "permission denied!");
4204 return WMError::WM_ERROR_NOT_SYSTEM_APP;
4205 }
4206 std::string callerBundleName = SessionPermission::GetCallingBundleName();
4207 TLOGD(WmsLogTag::WMS_EVENT, "enable:%{public}d name:%{public}s", enable, callerBundleName.c_str());
4208 auto task = [this, enable, bundleName = std::move(callerBundleName)]() {
4209 SessionManagerAgentController::GetInstance().NotifyGestureNavigationEnabledResult(enable);
4210 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
4211 WLOGFE("callback func is null");
4212 return WMError::WM_OK;
4213 }
4214 if (gestureNavigationEnabledChangeFunc_) {
4215 gestureNavigationEnabledChangeFunc_(enable, bundleName, GestureBackType::GESTURE_ALL);
4216 }
4217 if (statusBarEnabledChangeFunc_) {
4218 statusBarEnabledChangeFunc_(enable, bundleName);
4219 }
4220 return WMError::WM_OK;
4221 };
4222 return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
4223 }
4224
SetFocusedSessionId(int32_t persistentId)4225 WSError SceneSessionManager::SetFocusedSessionId(int32_t persistentId)
4226 {
4227 if (focusedSessionId_ == persistentId) {
4228 WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
4229 return WSError::WS_DO_NOTHING;
4230 }
4231 lastFocusedSessionId_ = focusedSessionId_;
4232 focusedSessionId_ = persistentId;
4233 return WSError::WS_OK;
4234 }
4235
GetFocusedSessionId() const4236 int32_t SceneSessionManager::GetFocusedSessionId() const
4237 {
4238 return focusedSessionId_;
4239 }
4240
GetFocusWindowInfo(FocusChangeInfo & focusInfo)4241 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
4242 {
4243 if (!SessionPermission::IsSACalling()) {
4244 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied!");
4245 return;
4246 }
4247 auto task = [this, &focusInfo] {
4248 if (auto sceneSession = GetSceneSession(focusedSessionId_)) {
4249 TLOGND(WmsLogTag::WMS_FOCUS, "Get focus session info success");
4250 focusInfo.windowId_ = sceneSession->GetWindowId();
4251 focusInfo.displayId_ = static_cast<DisplayId>(0);
4252 focusInfo.pid_ = sceneSession->GetCallingPid();
4253 focusInfo.uid_ = sceneSession->GetCallingUid();
4254 focusInfo.windowType_ = sceneSession->GetWindowType();
4255 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
4256 return WSError::WS_OK;
4257 }
4258 return WSError::WS_ERROR_DESTROYED_OBJECT;
4259 };
4260 taskScheduler_->PostSyncTask(task, __func__);
4261 }
4262
IsValidDigitString(const std::string & windowIdStr)4263 static bool IsValidDigitString(const std::string& windowIdStr)
4264 {
4265 if (windowIdStr.empty()) {
4266 return false;
4267 }
4268 for (char ch : windowIdStr) {
4269 if ((ch >= '0' && ch <= '9')) {
4270 continue;
4271 }
4272 WLOGFE("invalid window id");
4273 return false;
4274 }
4275 return true;
4276 }
4277
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)4278 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
4279 {
4280 if (sceneSession == nullptr) {
4281 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
4282 return;
4283 }
4284 const char* const where = __func__;
4285 sceneSession->SetSessionExceptionListener([this, where](
4286 const SessionInfo& info, bool needRemoveSession = false, bool startFail = false) {
4287 auto task = [this, info, where] {
4288 auto scnSession = GetSceneSession(info.persistentId_);
4289 if (scnSession == nullptr) {
4290 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s Not found session, id:%{public}d", where, info.persistentId_);
4291 return;
4292 }
4293 if (listenerController_ == nullptr) {
4294 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s listenerController_ is nullptr", where);
4295 return;
4296 }
4297 if (scnSession->GetSessionInfo().isSystem_) {
4298 TLOGNW(WmsLogTag::WMS_LIFE, "%{public}s id: %{public}d is system", where,
4299 scnSession->GetPersistentId());
4300 return;
4301 }
4302 TLOGNI(WmsLogTag::WMS_LIFE, "%{public}s errorCode: %{public}d, id: %{public}d",
4303 where, info.errorCode, info.persistentId_);
4304 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
4305 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
4306 TLOGND(WmsLogTag::WMS_LIFE, "NotifySessionClosed when ability load timeout "
4307 "or foreground timeout, id: %{public}d", info.persistentId_);
4308 listenerController_->NotifySessionClosed(info.persistentId_);
4309 }
4310 };
4311 taskScheduler_->PostVoidSyncTask(task, "sessionException");
4312 }, false);
4313 TLOGD(WmsLogTag::WMS_LIFE, "success, id: %{public}d", sceneSession->GetPersistentId());
4314 }
4315
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)4316 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
4317 {
4318 if (sceneSession == nullptr) {
4319 WLOGFE("session is nullptr");
4320 return;
4321 }
4322 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
4323 auto sceneSession = GetSceneSession(persistentId);
4324 if (sceneSession == nullptr) {
4325 WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
4326 return;
4327 }
4328 if (sceneSession->GetSessionInfo().isSystem_) {
4329 WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", sceneSession->GetPersistentId());
4330 return;
4331 }
4332 auto abilityInfoPtr = sceneSession->GetSessionInfo().abilityInfo;
4333 if (abilityInfoPtr == nullptr) {
4334 WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
4335 return;
4336 }
4337 if (listenerController_ == nullptr) {
4338 WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
4339 return;
4340 }
4341 if (!abilityInfoPtr->excludeFromMissions) {
4342 listenerController_->NotifySessionSnapshotChanged(persistentId);
4343 }
4344 };
4345 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
4346 WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
4347 }
4348
RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession> & sceneSession)4349 void SceneSessionManager::RegisterAcquireRotateAnimationConfigFunc(const sptr<SceneSession>& sceneSession)
4350 {
4351 if (sceneSession == nullptr) {
4352 TLOGE(WmsLogTag::DEFAULT, "session is nullptr");
4353 return;
4354 }
4355 AcquireRotateAnimationConfigFunc acquireRotateAnimationConfigFunc = [this](RotateAnimationConfig& config) {
4356 config.duration_ = rotateAnimationConfig_.duration_;
4357 };
4358 sceneSession->SetAcquireRotateAnimationConfigFunc(acquireRotateAnimationConfigFunc);
4359 TLOGD(WmsLogTag::DEFAULT, "Register acquire Rotate Animation config success, id: %{public}d",
4360 sceneSession->GetPersistentId());
4361 }
4362
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)4363 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
4364 {
4365 if (scnSession == nullptr) {
4366 WLOGFW("NotifySessionForCallback, scnSession is nullptr");
4367 return;
4368 }
4369 if (scnSession->GetSessionInfo().isSystem_) {
4370 WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
4371 return;
4372 }
4373 WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
4374 static_cast<uint32_t>(needRemoveSession));
4375 if (scnSession->GetSessionInfo().appIndex_ != 0) {
4376 WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
4377 scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
4378 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4379 return;
4380 }
4381 if (needRemoveSession) {
4382 WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
4383 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4384 return;
4385 }
4386 if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
4387 WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
4388 } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
4389 (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4390 WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
4391 scnSession->GetPersistentId());
4392 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
4393 return;
4394 }
4395 WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
4396 listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
4397 }
4398
NotifyWindowInfoChangeFromSession(int32_t persistentId)4399 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
4400 {
4401 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
4402 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4403 if (sceneSession == nullptr) {
4404 WLOGFE("sceneSession nullptr");
4405 return;
4406 }
4407
4408 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
4409 }
4410
IsSessionVisible(const sptr<SceneSession> & session)4411 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
4412 {
4413 if (session == nullptr) {
4414 return false;
4415 }
4416 if (Session::IsScbCoreEnabled()) {
4417 return session->IsVisible();
4418 }
4419 const auto& state = session->GetSessionState();
4420 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
4421 const auto& parentSceneSession = session->GetParentSession();
4422 if (parentSceneSession == nullptr) {
4423 WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
4424 return false;
4425 }
4426 const auto& parentState = parentSceneSession->GetSessionState();
4427 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
4428 if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
4429 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
4430 return false;
4431 }
4432 WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
4433 return true;
4434 }
4435 WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
4436 return false;
4437 }
4438
4439 if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
4440 WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
4441 return true;
4442 }
4443 WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
4444 return false;
4445 }
4446
IsSessionVisibleForeground(const sptr<SceneSession> & session)4447 bool SceneSessionManager::IsSessionVisibleForeground(const sptr<SceneSession>& session)
4448 {
4449 if (session == nullptr) {
4450 return false;
4451 }
4452 if (Session::IsScbCoreEnabled()) {
4453 return session->IsVisibleForeground();
4454 }
4455 return IsSessionVisible(session);
4456 }
4457
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)4458 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
4459 {
4460 if (session == nullptr) {
4461 return;
4462 }
4463 int32_t zOrder = IsSessionVisibleForeground(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
4464 WSRect rect = session->GetSessionRect();
4465 std::string sName;
4466 if (session->GetSessionInfo().isSystem_) {
4467 sName = session->GetSessionInfo().abilityName_;
4468 } else {
4469 sName = session->GetWindowName();
4470 }
4471 uint32_t flag = 0;
4472 uint64_t displayId = INVALID_SCREEN_ID;
4473 auto sessionProperty = session->GetSessionProperty();
4474 if (sessionProperty) {
4475 flag = sessionProperty->GetWindowFlags();
4476 displayId = sessionProperty->GetDisplayId();
4477 }
4478 uint32_t orientation = 0;
4479 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
4480 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
4481 // std::setw is used to set the output width and different width values are set to keep the format aligned.
4482 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
4483 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
4484 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
4485 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
4486 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
4487 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
4488 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
4489 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
4490 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
4491 << "[ "
4492 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
4493 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
4494 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
4495 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
4496 << "]"
4497 << " [ "
4498 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
4499 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
4500 << "]"
4501 << " [ "
4502 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
4503 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
4504 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
4505 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
4506 << "]"
4507 << std::endl;
4508 }
4509
GetAllSessionDumpInfo(std::string & dumpInfo)4510 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
4511 {
4512 int32_t screenGroupId = 0;
4513 std::ostringstream oss;
4514 oss << "-------------------------------------ScreenGroup " << screenGroupId
4515 << "-------------------------------------" << std::endl;
4516 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
4517 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]"
4518 << std::endl;
4519
4520 std::vector<sptr<SceneSession>> allSession;
4521 std::vector<sptr<SceneSession>> backgroundSession;
4522 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
4523 {
4524 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4525 sceneSessionMapCopy = sceneSessionMap_;
4526 }
4527 for (const auto& elem : sceneSessionMapCopy) {
4528 auto curSession = elem.second;
4529 if (curSession == nullptr || (!curSession->GetSessionInfo().isSystem_ && (curSession->GetSessionState() <
4530 SessionState::STATE_FOREGROUND || curSession->GetSessionState() > SessionState::STATE_BACKGROUND))) {
4531 WLOGFW("Session is nullptr or session state is invalid, id: %{public}d, state: %{public}u",
4532 curSession->GetPersistentId(), curSession->GetSessionState());
4533 continue;
4534 }
4535 if (IsSessionVisibleForeground(curSession)) {
4536 allSession.push_back(curSession);
4537 } else {
4538 backgroundSession.push_back(curSession);
4539 }
4540 }
4541 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
4542 uint32_t count = 0;
4543 for (const auto& session : allSession) {
4544 if (session == nullptr) {
4545 continue;
4546 }
4547 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
4548 oss << "---------------------------------------------------------------------------------------"
4549 << std::endl;
4550 }
4551 DumpSessionInfo(session, oss);
4552 count++;
4553 }
4554 oss << "Focus window: " << GetFocusedSessionId() << std::endl;
4555 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
4556 dumpInfo.append(oss.str());
4557 return WSError::WS_OK;
4558 }
4559
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)4560 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
4561 {
4562 dumpRootSceneFunc_ = func;
4563 }
4564
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)4565 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
4566 const std::vector<std::string>& params, std::string& dumpInfo)
4567 {
4568 std::vector<std::string> resetParams;
4569 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
4570 if (resetParams.empty()) {
4571 WLOGI("do not dump ui info");
4572 return;
4573 }
4574
4575 if (!session->GetSessionInfo().isSystem_) {
4576 WLOGFI("Dump normal session, not system");
4577 dumpInfoFuture_.ResetLock({});
4578 session->DumpSessionElementInfo(resetParams);
4579 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
4580 for (auto& info: infos) {
4581 dumpInfo.append(info).append("\n");
4582 }
4583 } else {
4584 WLOGFI("Dump system session");
4585 std::vector<std::string> infos;
4586 dumpRootSceneFunc_(resetParams, infos);
4587 for (auto& info: infos) {
4588 dumpInfo.append(info).append("\n");
4589 }
4590 }
4591 }
4592
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)4593 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
4594 const std::string& strId)
4595 {
4596 uint64_t persistentId = std::stoull(strId);
4597 auto session = GetSceneSession(persistentId);
4598 if (session == nullptr) {
4599 return WSError::WS_ERROR_INVALID_PARAM;
4600 }
4601 auto sessionProperty = session->GetSessionProperty();
4602 if (sessionProperty == nullptr) {
4603 return WSError::WS_ERROR_INVALID_PARAM;
4604 }
4605
4606 WSRect rect = session->GetSessionRect();
4607 std::string isVisible = session->IsVisible() ? "true" : "false";
4608 std::string focusable = session->GetFocusable() ? "true" : "false";
4609 std::string decoStatus = sessionProperty->IsDecorEnable() ? "true" : "false";
4610 bool privacyMode = sessionProperty->GetSystemPrivacyMode() || sessionProperty->GetPrivacyMode();
4611 std::string isPrivacyMode = privacyMode ? "true" : "false";
4612 bool isFirstFrameAvailable = true;
4613 std::ostringstream oss;
4614 oss << "WindowName: " << session->GetWindowName() << std::endl;
4615 oss << "DisplayId: " << 0 << std::endl;
4616 oss << "WinId: " << session->GetPersistentId() << std::endl;
4617 oss << "Pid: " << session->GetCallingPid() << std::endl;
4618 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
4619 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
4620 oss << "Flag: " << sessionProperty->GetWindowFlags() << std::endl;
4621 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
4622 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
4623 oss << "IsVisible: " << isVisible << std::endl;
4624 oss << "Focusable: " << focusable << std::endl;
4625 oss << "DecoStatus: " << decoStatus << std::endl;
4626 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
4627 oss << "WindowRect: " << "[ "
4628 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
4629 << " ]" << std::endl;
4630 oss << "scaleX: " << session->GetScaleX() << std::endl;
4631 oss << "scaleY: " << session->GetScaleY() << std::endl;
4632 oss << "Offset: " << "[ "
4633 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
4634 oss << "Scale: " << "[ "
4635 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
4636 << session->GetPivotX() << ", " << session->GetPivotY()
4637 << " ]" << std::endl;
4638 dumpInfo.append(oss.str());
4639
4640 DumpSessionElementInfo(session, params, dumpInfo);
4641 return WSError::WS_OK;
4642 }
4643
GetSCBDebugDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params)4644 WSError SceneSessionManager::GetSCBDebugDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params)
4645 {
4646 std::string cmd = ScbDumpSubscriber::JoinCommands(params, params.size());
4647
4648 // publish data
4649 bool ret = eventHandler_->PostSyncTask([this, cmd] { return g_scbSubscriber->Publish(cmd); }, "PublishSCBDumper");
4650 if (!ret) {
4651 return WSError::WS_ERROR_INVALID_OPERATION;
4652 }
4653
4654 // get response event
4655 auto task = [this, &dumpInfo]() {
4656 dumpInfo.append(g_scbSubscriber->GetDebugDumpInfo(WAIT_TIME));
4657 return WSError::WS_OK;
4658 };
4659 eventHandler_->PostSyncTask(task, "GetDataSCBDumper");
4660
4661 return WSError::WS_OK;
4662 }
4663
NotifyDumpInfoResult(const std::vector<std::string> & info)4664 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
4665 {
4666 dumpInfoFuture_.SetValue(info);
4667 WLOGFD("NotifyDumpInfoResult");
4668 }
4669
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)4670 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
4671 {
4672 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
4673 WLOGFE("GetSessionDumpInfo permission denied!");
4674 return WSError::WS_ERROR_INVALID_PERMISSION;
4675 }
4676
4677 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
4678 return GetAllSessionDumpInfo(dumpInfo);
4679 }
4680 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
4681 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
4682 }
4683 if (params.size() >= 2 && params[0] == ARG_DUMP_SCB) { // 2:params num
4684 return GetSCBDebugDumpInfo(dumpInfo, params);
4685 }
4686 if (params.size() >= 1 && params[0] == ARG_DUMP_PIPLINE) { // 1: params num
4687 return GetTotalUITreeInfo(dumpInfo);
4688 }
4689 return WSError::WS_ERROR_INVALID_OPERATION;
4690 }
4691
GetTotalUITreeInfo(std::string & dumpInfo)4692 WSError SceneSessionManager::GetTotalUITreeInfo(std::string& dumpInfo)
4693 {
4694 TLOGI(WmsLogTag::WMS_PIPELINE, "begin");
4695 if (dumpUITreeFunc_) {
4696 dumpUITreeFunc_(dumpInfo);
4697 } else {
4698 TLOGE(WmsLogTag::WMS_PIPELINE, "dumpUITreeFunc is null");
4699 }
4700 return WSError::WS_OK;
4701 }
4702
SetDumpUITreeFunc(const DumpUITreeFunc & func)4703 void SceneSessionManager::SetDumpUITreeFunc(const DumpUITreeFunc& func)
4704 {
4705 dumpUITreeFunc_ = func;
4706 }
4707
SetOnFlushUIParamsFunc(OnFlushUIParamsFunc && func)4708 void SceneSessionManager::SetOnFlushUIParamsFunc(OnFlushUIParamsFunc&& func)
4709 {
4710 onFlushUIParamsFunc_ = std::move(func);
4711 }
4712
SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc && func)4713 void SceneSessionManager::SetIsRootSceneLastFrameLayoutFinishedFunc(IsRootSceneLastFrameLayoutFinishedFunc&& func)
4714 {
4715 isRootSceneLastFrameLayoutFinishedFunc_ = std::move(func);
4716 }
4717
SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId,bool visible)4718 void SceneSessionManager::SetStatusBarDefaultVisibilityPerDisplay(DisplayId displayId, bool visible)
4719 {
4720 taskScheduler_->PostAsyncTask([this, displayId, visible] {
4721 statusBarDefaultVisibilityPerDisplay_[displayId] = visible;
4722 TLOGNI(WmsLogTag::WMS_IMMS,
4723 "set default visibility on display: %{public}" PRIu64 " visible: %{public}d", displayId, visible);
4724 }, __func__);
4725 }
4726
GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)4727 bool SceneSessionManager::GetStatusBarDefaultVisibilityByDisplayId(DisplayId displayId)
4728 {
4729 return statusBarDefaultVisibilityPerDisplay_.count(displayId) != 0 ?
4730 statusBarDefaultVisibilityPerDisplay_[displayId] : true;
4731 }
4732
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)4733 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
4734 {
4735 // notify RS
4736 WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
4737 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
4738 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
4739 sceneSession->GetSessionInfo().bundleName_.c_str(),
4740 sceneSession->GetSessionInfo().abilityName_.c_str(),
4741 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
4742 uint64_t focusNodeId = 0; // 0 means invalid
4743 if (sceneSession->GetSurfaceNode() == nullptr) {
4744 WLOGFW("focused window surfaceNode is null");
4745 } else {
4746 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
4747 }
4748 FocusAppInfo appInfo = {
4749 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
4750 sceneSession->GetSessionInfo().bundleName_,
4751 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
4752 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
4753 }
4754
4755 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)4756 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
4757 {
4758 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
4759 {
4760 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4761 for (auto& iter : sceneSessionMap_) {
4762 ret.push_back(iter);
4763 }
4764 }
4765 std::sort(ret.begin(), ret.end(), cmp);
4766 return ret;
4767 }
4768
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)4769 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
4770 {
4771 if (isFromTopToBottom) {
4772 TraverseSessionTreeFromTopToBottom(func);
4773 } else {
4774 TraverseSessionTreeFromBottomToTop(func);
4775 }
4776 return;
4777 }
4778
TraverseSessionTreeFromTopToBottom(TraverseFunc func)4779 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
4780 {
4781 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4782 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4783 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4784 return lhsZOrder < rhsZOrder;
4785 };
4786 auto sceneSessionVector = GetSceneSessionVector(cmp);
4787
4788 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
4789 auto session = iter->second;
4790 if (session == nullptr) {
4791 WLOGFE("session is nullptr");
4792 continue;
4793 }
4794 if (func(session)) {
4795 return;
4796 }
4797 }
4798 return;
4799 }
4800
TraverseSessionTreeFromBottomToTop(TraverseFunc func)4801 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
4802 {
4803 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4804 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
4805 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
4806 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
4807 return lhsZOrder < rhsZOrder;
4808 };
4809 auto sceneSessionVector = GetSceneSessionVector(cmp);
4810 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
4811 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
4812 auto session = iter->second;
4813 if (session == nullptr) {
4814 WLOGFE("session is nullptr");
4815 continue;
4816 }
4817 if (func(session)) {
4818 return;
4819 }
4820 }
4821 return;
4822 }
4823
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4824 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground,
4825 FocusChangeReason reason)
4826 {
4827 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4828 auto sceneSession = GetSceneSession(persistentId);
4829 if (sceneSession == nullptr) {
4830 TLOGE(WmsLogTag::WMS_FOCUS, "sceneSession is nullptr");
4831 return WMError::WM_ERROR_NULLPTR;
4832 }
4833 int32_t callingPid = IPCSkeleton::GetCallingPid();
4834 if (callingPid != sceneSession->GetCallingPid() &&
4835 !SessionPermission::IsSameAppAsCalling(SCENE_BOARD_BUNDLE_NAME, SCENE_BOARD_APP_IDENTIFIER)) {
4836 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
4837 return WMError::WM_ERROR_INVALID_CALLING;
4838 }
4839 auto task = [this, persistentId, isFocused, byForeground, reason]() {
4840 if (isFocused) {
4841 RequestSessionFocus(persistentId, byForeground, reason);
4842 } else {
4843 RequestSessionUnfocus(persistentId, reason);
4844 }
4845 };
4846 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
4847 focusChangeReason_ = reason;
4848 return WMError::WM_OK;
4849 }
4850
RequestFocusStatusBySCB(int32_t persistentId,bool isFocused,bool byForeground,FocusChangeReason reason)4851 WMError SceneSessionManager::RequestFocusStatusBySCB(int32_t persistentId, bool isFocused, bool byForeground,
4852 FocusChangeReason reason)
4853 {
4854 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d, reason: %{public}d", persistentId, reason);
4855 auto task = [this, persistentId, isFocused, byForeground, reason]() {
4856 if (isFocused) {
4857 if (reason == FocusChangeReason::FOREGROUND) {
4858 RequestSessionFocusImmediately(persistentId);
4859 return;
4860 }
4861 if (reason == FocusChangeReason::MOVE_UP) {
4862 auto session = GetSceneSession(persistentId);
4863 if (session && !session->IsFocused()) {
4864 PostProcessFocusState state = { true, true, reason };
4865 session->SetPostProcessFocusState(state);
4866 }
4867 return;
4868 }
4869 // need modifying the RequestFocusReason in SCBSceneSession.onClick() before remove this
4870 if (reason == FocusChangeReason::CLICK) {
4871 return;
4872 }
4873 if (RequestSessionFocus(persistentId, byForeground, reason) != WSError::WS_OK) {
4874 auto session = GetSceneSession(persistentId);
4875 if (session && !session->IsFocused()) {
4876 PostProcessFocusState state = { true, true, reason };
4877 session->SetPostProcessFocusState(state);
4878 }
4879 }
4880 } else {
4881 RequestSessionUnfocus(persistentId, reason);
4882 }
4883 };
4884 taskScheduler_->PostAsyncTask(task, "RequestFocusStatusBySCB" + std::to_string(persistentId));
4885 return WMError::WM_OK;
4886 }
4887
RequestAllAppSessionUnfocus()4888 void SceneSessionManager::RequestAllAppSessionUnfocus()
4889 {
4890 auto task = [this]() {
4891 RequestAllAppSessionUnfocusInner();
4892 };
4893 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
4894 return;
4895 }
4896
4897 /**
4898 * request focus and ignore its state
4899 * only used when app main window start before foreground
4900 */
RequestSessionFocusImmediately(int32_t persistentId)4901 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
4902 {
4903 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionFocusImmediately, id: %{public}d", persistentId);
4904 // base block
4905 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4906 if (basicCheckRet != WSError::WS_OK) {
4907 return basicCheckRet;
4908 }
4909 auto sceneSession = GetSceneSession(persistentId);
4910 if (sceneSession == nullptr) {
4911 WLOGFE("[WMSComm]session is nullptr");
4912 return WSError::WS_ERROR_INVALID_SESSION;
4913 }
4914 if (!sceneSession->GetFocusable()) {
4915 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable!");
4916 return WSError::WS_DO_NOTHING;
4917 }
4918 if (!sceneSession->IsFocusedOnShow()) {
4919 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4920 return WSError::WS_DO_NOTHING;
4921 }
4922
4923 // specific block
4924 FocusChangeReason reason = FocusChangeReason::SCB_START_APP;
4925 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true, reason);
4926 if (specificCheckRet != WSError::WS_OK) {
4927 return specificCheckRet;
4928 }
4929
4930 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4931 if (!sceneSession->GetSessionInfo().isSystem_ && !IsSessionVisibleForeground(sceneSession)) {
4932 needBlockNotifyFocusStatusUntilForeground_ = true;
4933 }
4934 ShiftFocus(sceneSession, reason);
4935 return WSError::WS_OK;
4936 }
4937
RequestSessionFocus(int32_t persistentId,bool byForeground,FocusChangeReason reason)4938 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground, FocusChangeReason reason)
4939 {
4940 TLOGD(WmsLogTag::WMS_FOCUS, "id: %{public}d, by foreground: %{public}d, reason: %{public}d",
4941 persistentId, byForeground, reason);
4942 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
4943 if (basicCheckRet != WSError::WS_OK) {
4944 return basicCheckRet;
4945 }
4946 auto sceneSession = GetSceneSession(persistentId);
4947 if (sceneSession == nullptr) {
4948 WLOGFE("[WMSComm]session is nullptr");
4949 return WSError::WS_ERROR_INVALID_SESSION;
4950 }
4951 if (!sceneSession->GetFocusable() || !IsSessionVisibleForeground(sceneSession)) {
4952 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable or not visible!");
4953 return WSError::WS_DO_NOTHING;
4954 }
4955 if (!sceneSession->IsFocusedOnShow()) {
4956 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focused on show!");
4957 return WSError::WS_DO_NOTHING;
4958 }
4959 if (!sceneSession->IsFocusableOnShow() &&
4960 (reason == FocusChangeReason::FOREGROUND || reason == FocusChangeReason::APP_FOREGROUND)) {
4961 TLOGD(WmsLogTag::WMS_FOCUS, "session is not focusable on show!");
4962 return WSError::WS_DO_NOTHING;
4963 }
4964
4965 // subwindow/dialog state block
4966 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
4967 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
4968 GetSceneSession(sceneSession->GetParentPersistentId()) &&
4969 !IsSessionVisibleForeground(GetSceneSession(sceneSession->GetParentPersistentId()))) {
4970 TLOGD(WmsLogTag::WMS_FOCUS, "parent session id: %{public}d is not visible!",
4971 sceneSession->GetParentPersistentId());
4972 return WSError::WS_DO_NOTHING;
4973 }
4974 // specific block
4975 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground, reason);
4976 if (specificCheckRet != WSError::WS_OK) {
4977 return specificCheckRet;
4978 }
4979
4980 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
4981 needBlockNotifyFocusStatusUntilForeground_ = false;
4982 ShiftFocus(sceneSession, reason);
4983 return WSError::WS_OK;
4984 }
4985
RequestSessionUnfocus(int32_t persistentId,FocusChangeReason reason)4986 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId, FocusChangeReason reason)
4987 {
4988 TLOGD(WmsLogTag::WMS_FOCUS, "RequestSessionUnfocus, id: %{public}d", persistentId);
4989 if (persistentId == INVALID_SESSION_ID) {
4990 WLOGFE("id is invalid");
4991 return WSError::WS_ERROR_INVALID_SESSION;
4992 }
4993 auto focusedSession = GetSceneSession(focusedSessionId_);
4994 if (persistentId != focusedSessionId_ &&
4995 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
4996 TLOGD(WmsLogTag::WMS_FOCUS, "session unfocused!");
4997 return WSError::WS_DO_NOTHING;
4998 }
4999 // if pop menu created by desktop request unfocus, back to desktop
5000 auto lastSession = GetSceneSession(lastFocusedSessionId_);
5001 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
5002 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
5003 RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
5004 TLOGD(WmsLogTag::WMS_FOCUS, "focus is back to desktop");
5005 return WSError::WS_OK;
5006 }
5007 auto nextSession = GetNextFocusableSession(persistentId);
5008 if (nextSession == nullptr) {
5009 DumpAllSessionFocusableInfo(persistentId);
5010 }
5011
5012 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5013 needBlockNotifyFocusStatusUntilForeground_ = false;
5014
5015 if (CheckLastFocusedAppSessionFocus(focusedSession, nextSession)) {
5016 return WSError::WS_OK;
5017 }
5018
5019 return ShiftFocus(nextSession, reason);
5020 }
5021
RequestAllAppSessionUnfocusInner()5022 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
5023 {
5024 TLOGI(WmsLogTag::WMS_FOCUS, "RequestAllAppSessionUnfocus");
5025 auto focusedSession = GetSceneSession(focusedSessionId_);
5026 if (!focusedSession) {
5027 TLOGE(WmsLogTag::WMS_FOCUS, "focused session is null");
5028 return WSError::WS_DO_NOTHING;
5029 }
5030 if (!focusedSession->IsAppSession()) {
5031 WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
5032 return WSError::WS_DO_NOTHING;
5033 }
5034 auto nextSession = GetTopFocusableNonAppSession();
5035
5036 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
5037 needBlockNotifyFocusStatusUntilForeground_ = false;
5038 return ShiftFocus(nextSession, FocusChangeReason::WIND);
5039 }
5040
RequestFocusBasicCheck(int32_t persistentId)5041 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
5042 {
5043 // basic focus rule
5044 if (persistentId == INVALID_SESSION_ID) {
5045 TLOGE(WmsLogTag::WMS_FOCUS, "id is invalid!");
5046 return WSError::WS_ERROR_INVALID_SESSION;
5047 }
5048 if (persistentId == focusedSessionId_) {
5049 TLOGD(WmsLogTag::WMS_FOCUS, "request id has been focused!");
5050 return WSError::WS_DO_NOTHING;
5051 }
5052 return WSError::WS_OK;
5053 }
5054
5055 /**
5056 * @note @window.focus
5057 * When high zOrder System Session unfocus, check if the last focused app window can focus.
5058 */
CheckLastFocusedAppSessionFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & nextSession)5059 bool SceneSessionManager::CheckLastFocusedAppSessionFocus(
5060 sptr<SceneSession>& focusedSession, sptr<SceneSession>& nextSession)
5061 {
5062 if (focusedSession == nullptr || nextSession == nullptr) {
5063 return false;
5064 }
5065
5066 TLOGI(WmsLogTag::WMS_FOCUS, "lastFocusedAppSessionId: %{public}d, nextSceneSession: %{public}d",
5067 lastFocusedAppSessionId_, nextSession->GetPersistentId());
5068
5069 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || nextSession->GetPersistentId() == lastFocusedAppSessionId_) {
5070 return false;
5071 }
5072
5073 if (!focusedSession->IsSystemSessionAboveApp()) {
5074 return false;
5075 }
5076
5077 auto mode = nextSession->GetWindowMode();
5078 // only when next session is app, and in split or floation
5079 if (nextSession->IsAppSession() &&
5080 (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
5081 mode == WindowMode::WINDOW_MODE_FLOATING)) {
5082 if (RequestSessionFocus(lastFocusedAppSessionId_, false, FocusChangeReason::LAST_FOCUSED_APP) ==
5083 WSError::WS_OK) {
5084 return true;
5085 }
5086 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5087 }
5088 return false;
5089 }
5090
5091 /**
5092 * When switching focus, check if the blockingType window has been traversed downwards.
5093 *
5094 * @return true: traversed downwards, false: not.
5095 */
CheckFocusIsDownThroughBlockingType(sptr<SceneSession> & requestSceneSession,sptr<SceneSession> & focusedSession,bool includingAppSession)5096 bool SceneSessionManager::CheckFocusIsDownThroughBlockingType(sptr<SceneSession>& requestSceneSession,
5097 sptr<SceneSession>& focusedSession, bool includingAppSession)
5098 {
5099 uint32_t requestSessionZOrder = requestSceneSession->GetZOrder();
5100 uint32_t focusedSessionZOrder = focusedSession->GetZOrder();
5101 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d",
5102 requestSessionZOrder, focusedSessionZOrder);
5103 if (requestSessionZOrder < focusedSessionZOrder) {
5104 auto topNearestBlockingFocusSession = GetTopNearestBlockingFocusSession(requestSessionZOrder,
5105 includingAppSession);
5106 uint32_t topNearestBlockingZOrder = 0;
5107 if (topNearestBlockingFocusSession) {
5108 topNearestBlockingZOrder = topNearestBlockingFocusSession->GetZOrder();
5109 TLOGD(WmsLogTag::WMS_FOCUS, "requestSessionZOrder: %{public}d, focusedSessionZOrder: %{public}d\
5110 topNearestBlockingZOrder: %{public}d", requestSessionZOrder, focusedSessionZOrder,
5111 topNearestBlockingZOrder);
5112 }
5113 if (focusedSessionZOrder >= topNearestBlockingZOrder && requestSessionZOrder < topNearestBlockingZOrder) {
5114 TLOGD(WmsLogTag::WMS_FOCUS, "focus pass through, needs to be intercepted");
5115 return true;
5116 }
5117 }
5118 TLOGD(WmsLogTag::WMS_FOCUS, "not through");
5119 return false;
5120 }
5121
CheckTopmostWindowFocus(sptr<SceneSession> & focusedSession,sptr<SceneSession> & sceneSession)5122 bool SceneSessionManager::CheckTopmostWindowFocus(sptr<SceneSession>& focusedSession, sptr<SceneSession>& sceneSession)
5123 {
5124 bool isFocusedMainSessionTopmost =
5125 focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && focusedSession->IsTopmost();
5126 auto parentSession = GetSceneSession(focusedSession->GetParentPersistentId());
5127 bool isFocusedSessionParentTopmost = parentSession &&
5128 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW && parentSession->IsTopmost();
5129 if ((isFocusedMainSessionTopmost || isFocusedSessionParentTopmost) && sceneSession->IsAppSession() &&
5130 (sceneSession->GetMissionId() != focusedSession->GetMissionId())) {
5131 return true;
5132 }
5133 return false;
5134 }
5135
CheckRequestFocusImmdediately(sptr<SceneSession> & sceneSession)5136 bool SceneSessionManager::CheckRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
5137 {
5138 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
5139 (SessionHelper::IsSubWindow(sceneSession->GetWindowType()) && !sceneSession->IsModal())) &&
5140 (ProcessModalTopmostRequestFocusImmdediately(sceneSession) == WSError::WS_OK ||
5141 ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK)) {
5142 TLOGD(WmsLogTag::WMS_FOCUS, "dialog or modal subwindow get focused");
5143 return true;
5144 }
5145 return false;
5146 }
5147
CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession> & focusedSession,const sptr<SceneSession> & sceneSession,FocusChangeReason reason)5148 bool SceneSessionManager::CheckClickFocusIsDownThroughFullScreen(const sptr<SceneSession>& focusedSession,
5149 const sptr<SceneSession>& sceneSession, FocusChangeReason reason)
5150 {
5151 if (focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_GLOBAL_SEARCH &&
5152 focusedSession->GetWindowType() != WindowType::WINDOW_TYPE_NEGATIVE_SCREEN) {
5153 return false;
5154 }
5155 if (reason != FocusChangeReason::CLICK || !focusedSession->GetBlockingFocus()) {
5156 return false;
5157 }
5158 return sceneSession->GetZOrder() < focusedSession->GetZOrder();
5159 }
5160
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground,FocusChangeReason reason)5161 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground,
5162 FocusChangeReason reason)
5163 {
5164 TLOGD(WmsLogTag::WMS_FOCUS, "FocusChangeReason: %{public}d", reason);
5165 int32_t persistentId = sceneSession->GetPersistentId();
5166 if (sceneSession->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5167 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5168 return WSError::WS_ERROR_INVALID_OPERATION;
5169 }
5170 // dialog get focus
5171 if (CheckRequestFocusImmdediately(sceneSession)) {
5172 return WSError::WS_DO_NOTHING;
5173 }
5174 // blocking-type session will block lower zOrder request focus
5175 auto focusedSession = GetSceneSession(focusedSessionId_);
5176 if (focusedSession) {
5177 TLOGD(WmsLogTag::WMS_FOCUS, "reason: %{public}d, byForeground: %{public}d", reason,
5178 byForeground);
5179 if (CheckTopmostWindowFocus(focusedSession, sceneSession)) {
5180 // return ok if focused session is topmost
5181 return WSError::WS_OK;
5182 }
5183 if (reason == FocusChangeReason::CLIENT_REQUEST && sceneSession->IsAppSession() &&
5184 sceneSession->GetMissionId() == focusedSession->GetMissionId()) {
5185 TLOGD(WmsLogTag::WMS_FOCUS, "client request from the same app, skip blocking check");
5186 byForeground = false;
5187 }
5188 if (byForeground && CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, true)) {
5189 TLOGD(WmsLogTag::WMS_FOCUS, "check, need to be intercepted");
5190 return WSError::WS_DO_NOTHING;
5191 }
5192 if ((reason == FocusChangeReason::SPLIT_SCREEN || reason == FocusChangeReason::FLOATING_SCENE) &&
5193 !byForeground) {
5194 if (!CheckFocusIsDownThroughBlockingType(sceneSession, focusedSession, false)
5195 && focusedSession->IsAppSession()) {
5196 TLOGD(WmsLogTag::WMS_FOCUS, "in split or floting , ok");
5197 return WSError::WS_OK;
5198 }
5199 }
5200 bool isBlockingType = focusedSession->IsAppSession() ||
5201 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
5202 // temp check
5203 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
5204 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
5205 TLOGD(WmsLogTag::WMS_FOCUS, "Lower session %{public}d cannot request focus from keyguard!",
5206 persistentId);
5207 return WSError::WS_DO_NOTHING;
5208 }
5209 // desktop click temp check
5210 if (CheckClickFocusIsDownThroughFullScreen(focusedSession, sceneSession, reason)) {
5211 TLOGW(WmsLogTag::WMS_FOCUS, "click cannot request focus from full screen window!");
5212 return WSError::WS_DO_NOTHING;
5213 }
5214 }
5215 return WSError::WS_OK;
5216 }
5217
CheckParentSessionVisible(const sptr<SceneSession> & session)5218 bool SceneSessionManager::CheckParentSessionVisible(const sptr<SceneSession>& session)
5219 {
5220 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
5221 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
5222 GetSceneSession(session->GetParentPersistentId()) &&
5223 !IsSessionVisibleForeground(GetSceneSession(session->GetParentPersistentId()))) {
5224 return false;
5225 }
5226 return true;
5227 }
5228
DumpAllSessionFocusableInfo(int32_t persistentId)5229 void SceneSessionManager::DumpAllSessionFocusableInfo(int32_t persistentId)
5230 {
5231 TLOGI(WmsLogTag::WMS_FOCUS, "id: %{public}d", persistentId);
5232 auto func = [this](sptr<SceneSession> session) {
5233 if (session == nullptr) {
5234 return false;
5235 }
5236 bool parentVisible = CheckParentSessionVisible(session);
5237 bool sessionVisible = IsSessionVisible(session);
5238 TLOGI(WmsLogTag::WMS_FOCUS, "%{public}d, winType:%{public}d, hide:%{public}d, "
5239 "focusable:%{public}d, visible:%{public}d, parentVisible:%{public}d",
5240 session->GetPersistentId(), session->GetWindowType(), session->GetForceHideState(),
5241 session->GetFocusable(), sessionVisible, parentVisible);
5242 return false;
5243 };
5244 TraverseSessionTree(func, true);
5245 }
5246
GetNextFocusableSession(int32_t persistentId)5247 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
5248 {
5249 TLOGD(WmsLogTag::WMS_FOCUS, "GetNextFocusableSession, id: %{public}d", persistentId);
5250 bool previousFocusedSessionFound = false;
5251 sptr<SceneSession> ret = nullptr;
5252 auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
5253 if (session == nullptr) {
5254 return false;
5255 }
5256 if (session->GetForceHideState() != ForceHideState::NOT_HIDDEN) {
5257 TLOGD(WmsLogTag::WMS_FOCUS, "the window hide id: %{public}d", persistentId);
5258 return false;
5259 }
5260 if (previousFocusedSessionFound && session->GetFocusable() &&
5261 IsSessionVisibleForeground(session) && CheckParentSessionVisible(session)) {
5262 ret = session;
5263 return true;
5264 }
5265 if (session->GetPersistentId() == persistentId) {
5266 previousFocusedSessionFound = true;
5267 }
5268 return false;
5269 };
5270 TraverseSessionTree(func, true);
5271 return ret;
5272 }
5273
5274 /**
5275 * Find the session through the specific zOrder, it is located abve it, its' blockingFocus attribute is true,
5276 * and it is the closest;
5277 */
GetTopNearestBlockingFocusSession(uint32_t zOrder,bool includingAppSession)5278 sptr<SceneSession> SceneSessionManager::GetTopNearestBlockingFocusSession(uint32_t zOrder, bool includingAppSession)
5279 {
5280 sptr<SceneSession> ret = nullptr;
5281 auto func = [this, &ret, zOrder, includingAppSession](sptr<SceneSession> session) {
5282 if (session == nullptr) {
5283 return false;
5284 }
5285 uint32_t sessionZOrder = session->GetZOrder();
5286 if (sessionZOrder <= zOrder) { // must be above the target session
5287 return false;
5288 }
5289 if (session->IsTopmost() && session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5290 TLOGD(WmsLogTag::WMS_FOCUS, "topmost window do not block");
5291 return false;
5292 }
5293 auto parentSession = GetSceneSession(session->GetParentPersistentId());
5294 if (SessionHelper::IsSubWindow(session->GetWindowType()) && parentSession != nullptr &&
5295 parentSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5296 parentSession->IsTopmost()) {
5297 TLOGD(WmsLogTag::WMS_FOCUS, "sub window of topmost do not block");
5298 return false;
5299 }
5300 bool isPhoneOrPad = systemConfig_.uiType_ == UI_TYPE_PHONE || systemConfig_.uiType_ == UI_TYPE_PAD;
5301 bool isBlockingType = (includingAppSession && session->IsAppSession()) ||
5302 (session->GetSessionInfo().isSystem_ && session->GetBlockingFocus()) ||
5303 (isPhoneOrPad && session->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION);
5304 if (IsSessionVisibleForeground(session) && isBlockingType) {
5305 ret = session;
5306 return true;
5307 }
5308 return false;
5309 };
5310 TraverseSessionTree(func, false);
5311 return ret;
5312 }
5313
GetTopFocusableNonAppSession()5314 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
5315 {
5316 TLOGD(WmsLogTag::WMS_FOCUS, "GetTopFocusableNonAppSession.");
5317 sptr<SceneSession> ret = nullptr;
5318 auto func = [this, &ret](sptr<SceneSession> session) {
5319 if (session == nullptr) {
5320 return false;
5321 }
5322 if (session->IsAppSession()) {
5323 return true;
5324 }
5325 if (session->GetFocusable() && IsSessionVisibleForeground(session)) {
5326 ret = session;
5327 }
5328 return false;
5329 };
5330 TraverseSessionTree(func, false);
5331 return ret;
5332 }
5333
SetShiftFocusListener(const ProcessShiftFocusFunc & func)5334 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
5335 {
5336 TLOGD(WmsLogTag::WMS_FOCUS, "SetShiftFocusListener");
5337 shiftFocusFunc_ = func;
5338 }
5339
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5340 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5341 {
5342 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBFocusedListener");
5343 notifySCBAfterFocusedFunc_ = func;
5344 }
5345
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)5346 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
5347 {
5348 TLOGD(WmsLogTag::WMS_FOCUS, "SetSCBUnfocusedListener");
5349 notifySCBAfterUnfocusedFunc_ = func;
5350 }
5351
SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc & func)5352 void SceneSessionManager::SetCallingSessionIdSessionListenser(const ProcessCallingSessionIdChangeFunc& func)
5353 {
5354 WLOGFD("SetCallingSessionIdSessionListenser");
5355 callingSessionIdChangeFunc_ = func;
5356 }
5357
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)5358 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
5359 {
5360 WLOGFD("SetStartUIAbilityErrorListener");
5361 startUIAbilityErrorFunc_ = func;
5362 }
5363
SetAbilityManagerCollaboratorRegisteredFunc(const AbilityManagerCollaboratorRegisteredFunc & func)5364 void SceneSessionManager::SetAbilityManagerCollaboratorRegisteredFunc(
5365 const AbilityManagerCollaboratorRegisteredFunc& func)
5366 {
5367 auto task = [this, func] {
5368 abilityManagerCollaboratorRegisteredFunc_ = func;
5369 };
5370 taskScheduler_->PostAsyncTask(task, __func__);
5371 }
5372
ShiftFocus(sptr<SceneSession> & nextSession,FocusChangeReason reason)5373 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession, FocusChangeReason reason)
5374 {
5375 // unfocus
5376 int32_t focusedId = focusedSessionId_;
5377 auto focusedSession = GetSceneSession(focusedSessionId_);
5378 UpdateFocusStatus(focusedSession, false);
5379 // focus
5380 int32_t nextId = INVALID_SESSION_ID;
5381 if (nextSession == nullptr) {
5382 std::string sessionLog(GetAllSessionFocusInfo());
5383 TLOGW(WmsLogTag::WMS_FOCUS, "ShiftFocus to nullptr! id: %{public}d, info: %{public}s",
5384 focusedSessionId_, sessionLog.c_str());
5385 } else {
5386 nextId = nextSession->GetPersistentId();
5387 }
5388 UpdateFocusStatus(nextSession, true);
5389 if (shiftFocusFunc_ != nullptr) {
5390 shiftFocusFunc_(nextId);
5391 }
5392 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
5393 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
5394 if (!scbPrevFocus && scbCurrFocus) {
5395 if (notifySCBAfterFocusedFunc_ != nullptr) {
5396 notifySCBAfterFocusedFunc_();
5397 }
5398 } else if (scbPrevFocus && !scbCurrFocus) {
5399 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
5400 notifySCBAfterUnfocusedFunc_();
5401 }
5402 }
5403 TLOGI(WmsLogTag::WMS_FOCUS, "ShiftFocus, focusedId: %{public}d, nextId: %{public}d, reason: %{public}d",
5404 focusedId, nextId, reason);
5405 return WSError::WS_OK;
5406 }
5407
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5408 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5409 {
5410 if (sceneSession == nullptr) {
5411 if (isFocused) {
5412 SetFocusedSessionId(INVALID_SESSION_ID);
5413 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
5414 }
5415 return;
5416 }
5417 TLOGD(WmsLogTag::WMS_FOCUS, "UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
5418 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
5419 // set focused
5420 if (isFocused) {
5421 SetFocusedSessionId(sceneSession->GetPersistentId());
5422 if (sceneSession->IsAppOrLowerSystemSession()) {
5423 lastFocusedAppSessionId_ = sceneSession->GetPersistentId();
5424 }
5425 }
5426 sceneSession->UpdateFocus(isFocused);
5427 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
5428 NotifyFocusStatus(sceneSession, isFocused);
5429 }
5430 }
5431
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)5432 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
5433 {
5434 if (sceneSession == nullptr) {
5435 WLOGFE("[WMSComm]session is nullptr");
5436 if (isFocused) {
5437 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5438 NotifyUnFocusedByMission(prevSession);
5439 }
5440 return;
5441 }
5442 int32_t persistentId = sceneSession->GetPersistentId();
5443
5444 TLOGI(WmsLogTag::WMS_FOCUS,
5445 "name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
5446 sceneSession->GetSessionInfo().bundleName_.c_str(),
5447 sceneSession->GetSessionInfo().abilityName_.c_str(),
5448 sceneSession->GetWindowNameAllType().c_str(),
5449 persistentId, isFocused);
5450 if (isFocused) {
5451 if (IsSessionVisibleForeground(sceneSession)) {
5452 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
5453 }
5454 UpdateBrightness(focusedSessionId_);
5455 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
5456 }
5457 // notify window manager
5458 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5459 sceneSession->GetWindowId(),
5460 static_cast<DisplayId>(0),
5461 sceneSession->GetCallingPid(),
5462 sceneSession->GetCallingUid(),
5463 sceneSession->GetWindowType(),
5464 sceneSession->GetAbilityToken()
5465 );
5466 SceneSessionManager::NotifyRssThawApp(focusChangeInfo->uid_, "", "THAW_BY_FOCUS_CHANGED");
5467 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5468 sceneSession->NotifyFocusStatus(isFocused);
5469 // notify listenerController
5470 auto prevSession = GetSceneSession(lastFocusedSessionId_);
5471 if (isFocused && MissionChanged(prevSession, sceneSession)) {
5472 NotifyFocusStatusByMission(prevSession, sceneSession);
5473 }
5474 }
5475
NotifyRssThawApp(const int32_t uid,const std::string & bundleName,const std::string & reason)5476 int32_t SceneSessionManager::NotifyRssThawApp(const int32_t uid, const std::string& bundleName,
5477 const std::string& reason)
5478 {
5479 uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
5480 nlohmann::json payload;
5481 payload.emplace("uid", uid);
5482 payload.emplace("bundleName", bundleName);
5483 payload.emplace("reason", reason);
5484 nlohmann::json reply;
5485 int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
5486 return ret;
5487 }
5488
NotifyFocusStatusByMission(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5489 void SceneSessionManager::NotifyFocusStatusByMission(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5490 {
5491 if (listenerController_ != nullptr) {
5492 if (prevSession && !prevSession->GetSessionInfo().isSystem_) {
5493 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", prevSession->GetMissionId());
5494 listenerController_->NotifySessionUnfocused(prevSession->GetMissionId());
5495 }
5496 if (currSession && !currSession->GetSessionInfo().isSystem_) {
5497 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionFocused, id: %{public}d", currSession->GetMissionId());
5498 listenerController_->NotifySessionFocused(currSession->GetMissionId());
5499 }
5500 }
5501 }
5502
NotifyUnFocusedByMission(sptr<SceneSession> & sceneSession)5503 void SceneSessionManager::NotifyUnFocusedByMission(sptr<SceneSession>& sceneSession)
5504 {
5505 if (listenerController_ == nullptr) {
5506 return;
5507 }
5508 if (sceneSession && !sceneSession->GetSessionInfo().isSystem_) {
5509 TLOGD(WmsLogTag::WMS_FOCUS, "NotifyMissionUnfocused, id: %{public}d", sceneSession->GetMissionId());
5510 listenerController_->NotifySessionUnfocused(sceneSession->GetMissionId());
5511 }
5512 }
5513
MissionChanged(sptr<SceneSession> & prevSession,sptr<SceneSession> & currSession)5514 bool SceneSessionManager::MissionChanged(sptr<SceneSession>& prevSession, sptr<SceneSession>& currSession)
5515 {
5516 if (prevSession == nullptr && currSession == nullptr) {
5517 return false;
5518 }
5519 if (prevSession == nullptr || currSession == nullptr) {
5520 return true;
5521 }
5522 return prevSession->GetMissionId() != currSession->GetMissionId();
5523 }
5524
GetAllSessionFocusInfo()5525 std::string SceneSessionManager::GetAllSessionFocusInfo()
5526 {
5527 std::ostringstream os;
5528 auto func = [&os](sptr<SceneSession> session) {
5529 if (session == nullptr) {
5530 WLOGE("sceneSession is nullptr");
5531 return false;
5532 }
5533 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
5534 " ,focusable: "<< session->GetFocusable() << ";";
5535 return false;
5536 };
5537 TraverseSessionTree(func, true);
5538 return os.str();
5539 }
5540
UpdateFocus(int32_t persistentId,bool isFocused)5541 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
5542 {
5543 auto task = [this, persistentId, isFocused]() {
5544 // notify session and client
5545 auto sceneSession = GetSceneSession(persistentId);
5546 if (sceneSession == nullptr) {
5547 WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
5548 return WSError::WS_ERROR_INVALID_WINDOW;
5549 }
5550 WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
5551 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
5552 // focusId change
5553 if (isFocused) {
5554 SetFocusedSessionId(persistentId);
5555 UpdateBrightness(focusedSessionId_);
5556 FocusIDChange(persistentId, sceneSession);
5557 } else if (persistentId == GetFocusedSessionId()) {
5558 SetFocusedSessionId(INVALID_SESSION_ID);
5559 }
5560 // notify window manager
5561 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
5562 sceneSession->GetWindowId(),
5563 static_cast<DisplayId>(0),
5564 sceneSession->GetCallingPid(),
5565 sceneSession->GetCallingUid(),
5566 sceneSession->GetWindowType(),
5567 sceneSession->GetAbilityToken()
5568 );
5569 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
5570 WSError res = WSError::WS_OK;
5571 res = sceneSession->UpdateFocus(isFocused);
5572 if (res != WSError::WS_OK) {
5573 return res;
5574 }
5575 WLOGFI("UpdateFocus, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
5576 sceneSession->GetSessionInfo().isSystem_);
5577 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
5578 if (isFocused) {
5579 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
5580 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
5581 } else {
5582 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
5583 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
5584 }
5585 }
5586 return WSError::WS_OK;
5587 };
5588
5589 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
5590 return WSError::WS_OK;
5591 }
5592
UpdateWindowMode(int32_t persistentId,int32_t windowMode)5593 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
5594 {
5595 WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
5596 auto sceneSession = GetSceneSession(persistentId);
5597 if (sceneSession == nullptr) {
5598 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
5599 return WSError::WS_ERROR_INVALID_WINDOW;
5600 }
5601 WindowMode mode = static_cast<WindowMode>(windowMode);
5602 return sceneSession->UpdateWindowMode(mode);
5603 }
5604
5605 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)5606 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
5607 MMI::PointerEvent::PointerItem& pointerItem)
5608 {
5609 struct PointerEventData {
5610 double x;
5611 double y;
5612 uint64_t time;
5613 } pointerEventData = {
5614 .x = pointerItem.GetDisplayX(),
5615 .y = pointerItem.GetDisplayY(),
5616 .time = pointerEvent->GetActionTime()
5617 };
5618
5619 const uint32_t MAX_HMAC_SIZE = 64;
5620 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
5621 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
5622 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
5623 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
5624 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
5625 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
5626 }
5627 }
5628 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
5629
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)5630 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
5631 {
5632 if (!pointerEvent) {
5633 WLOGFE("pointerEvent is null");
5634 return WSError::WS_ERROR_NULLPTR;
5635 }
5636 MMI::PointerEvent::PointerItem pointerItem;
5637 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
5638 WLOGFE("Failed to get pointerItem");
5639 return WSError::WS_ERROR_INVALID_PARAM;
5640 }
5641 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
5642 FillSecCompEnhanceData(pointerEvent, pointerItem);
5643 #endif
5644 TLOGI(WmsLogTag::WMS_EVENT, "PointerId=%{public}d,action=%{public}d,deviceId=%{public}d,zIndex=%{public}ud",
5645 pointerEvent->GetPointerId(), pointerEvent->GetPointerAction(), pointerEvent->GetDeviceId(), zIndex);
5646 pointerEvent->AddFlag(MMI::PointerEvent::EVENT_FLAG_NO_INTERCEPT);
5647 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
5648 return WSError::WS_OK;
5649 }
5650
SetScreenLocked(const bool isScreenLocked)5651 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
5652 {
5653 isScreenLocked_ = isScreenLocked;
5654 DeleteStateDetectTask();
5655 }
5656
SetUserAuthPassed(bool isUserAuthPassed)5657 void SceneSessionManager::SetUserAuthPassed(bool isUserAuthPassed)
5658 {
5659 taskScheduler_->PostTask([this, isUserAuthPassed] {
5660 isUserAuthPassed_ = isUserAuthPassed;
5661 }, __func__);
5662 }
5663
DeleteStateDetectTask()5664 void SceneSessionManager::DeleteStateDetectTask()
5665 {
5666 if (!IsScreenLocked()) {
5667 return;
5668 }
5669 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5670 for (auto iter : sceneSessionMap_) {
5671 auto& session = iter.second;
5672 if (session && session->GetDetectTaskInfo().taskState != DetectTaskState::NO_TASK) {
5673 taskScheduler_->GetEventHandler()->RemoveTask(session->GetWindowDetectTaskName());
5674 DetectTaskInfo detectTaskInfo;
5675 session->SetDetectTaskInfo(detectTaskInfo);
5676 }
5677 }
5678 }
5679
IsScreenLocked() const5680 bool SceneSessionManager::IsScreenLocked() const
5681 {
5682 return isScreenLocked_;
5683 }
5684
IsUserAuthPassed() const5685 bool SceneSessionManager::IsUserAuthPassed() const
5686 {
5687 return isUserAuthPassed_;
5688 }
5689
RegisterWindowChanged(const WindowChangedFunc & func)5690 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
5691 {
5692 WindowChangedFunc_ = func;
5693 }
5694
JudgeNeedNotifyPrivacyInfo(DisplayId displayId,const std::unordered_set<std::string> & privacyBundles)5695 bool SceneSessionManager::JudgeNeedNotifyPrivacyInfo(DisplayId displayId,
5696 const std::unordered_set<std::string>& privacyBundles)
5697 {
5698 bool needNotify = false;
5699 static int reSendTimes = MAX_RESEND_TIMES;
5700 std::unique_lock<std::mutex> lock(privacyBundleMapMutex_);
5701 do {
5702 if (privacyBundleMap_.find(displayId) == privacyBundleMap_.end()) {
5703 TLOGD(WmsLogTag::WMS_MAIN, "can not find display[%{public}" PRIu64 "].", displayId);
5704 needNotify = !privacyBundles.empty();
5705 break;
5706 }
5707 const auto& lastPrivacyBundles = privacyBundleMap_[displayId];
5708 if (lastPrivacyBundles.size() != privacyBundles.size()) {
5709 TLOGD(WmsLogTag::WMS_MAIN, "privacy bundle list size is not equal, %{public}zu != %{public}zu.",
5710 lastPrivacyBundles.size(), privacyBundles.size());
5711 needNotify = true;
5712 break;
5713 }
5714 for (const auto& bundle : lastPrivacyBundles) {
5715 if (privacyBundles.find(bundle) == privacyBundles.end()) {
5716 needNotify = true;
5717 break;
5718 }
5719 }
5720 } while (false);
5721
5722 TLOGD(WmsLogTag::WMS_MAIN, "display[%{public}" PRIu64 "] need notify privacy state: %{public}d.",
5723 displayId, needNotify);
5724 if (needNotify) {
5725 reSendTimes = MAX_RESEND_TIMES;
5726 privacyBundleMap_[displayId] = privacyBundles;
5727 } else if (reSendTimes > 0) {
5728 needNotify = true;
5729 reSendTimes--;
5730 privacyBundleMap_[displayId] = privacyBundles;
5731 }
5732 return needNotify;
5733 }
5734
UpdatePrivateStateAndNotify(uint32_t persistentId)5735 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
5736 {
5737 auto sceneSession = GetSceneSession(persistentId);
5738 if (sceneSession == nullptr) {
5739 TLOGE(WmsLogTag::WMS_MAIN, "update privacy state failed, scene is nullptr, wid = %{public}u.", persistentId);
5740 return;
5741 }
5742
5743 auto sessionProperty = sceneSession->GetSessionProperty();
5744 if (sessionProperty == nullptr) {
5745 TLOGE(WmsLogTag::WMS_MAIN, "get session property failed, wid = %{public}u.", persistentId);
5746 return;
5747 }
5748 auto displayId = sessionProperty->GetDisplayId();
5749 std::unordered_set<std::string> privacyBundleList;
5750 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5751 if (isUserBackground_ || !JudgeNeedNotifyPrivacyInfo(displayId, privacyBundleList)) {
5752 return;
5753 }
5754
5755 std::vector<std::string> bundleListForNotify(privacyBundleList.begin(), privacyBundleList.end());
5756 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5757 !bundleListForNotify.empty() || specialExtWindowHasPrivacyMode_.load());
5758 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyWindowList(displayId, bundleListForNotify);
5759 if (!bundleListForNotify.empty()) {
5760 TLOGI(WmsLogTag::WMS_MAIN, "first privacy window bundle name: %{public}s.", bundleListForNotify[0].c_str());
5761 }
5762 for (const auto& bundle : bundleListForNotify) {
5763 TLOGD(WmsLogTag::WMS_MAIN, "notify dms privacy bundle, display = %{public}" PRIu64 ", bundle = %{public}s.",
5764 displayId, bundle.c_str());
5765 }
5766 }
5767
UpdatePrivateStateAndNotifyForAllScreens()5768 void SceneSessionManager::UpdatePrivateStateAndNotifyForAllScreens()
5769 {
5770 auto screenProperties = ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
5771 for (auto& iter : screenProperties) {
5772 auto displayId = iter.first;
5773 std::unordered_set<std::string> privacyBundleList;
5774 GetSceneSessionPrivacyModeBundles(displayId, privacyBundleList);
5775
5776 ScreenSessionManagerClient::GetInstance().SetPrivacyStateByDisplayId(displayId,
5777 !privacyBundleList.empty() || specialExtWindowHasPrivacyMode_.load());
5778 }
5779 }
5780
GetSceneSessionPrivacyModeBundles(DisplayId displayId,std::unordered_set<std::string> & privacyBundles)5781 void SceneSessionManager::GetSceneSessionPrivacyModeBundles(DisplayId displayId,
5782 std::unordered_set<std::string>& privacyBundles)
5783 {
5784 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5785 for (const auto& item : sceneSessionMap_) {
5786 sptr<SceneSession> sceneSession = item.second;
5787 if (sceneSession == nullptr) {
5788 TLOGE(WmsLogTag::WMS_MAIN, "scene session is nullptr, wid = %{public}d.", item.first);
5789 continue;
5790 }
5791 auto sessionProperty = sceneSession->GetSessionProperty();
5792 if (sessionProperty == nullptr) {
5793 TLOGE(WmsLogTag::WMS_MAIN, "scene session property is nullptr, wid = %{public}d.", item.first);
5794 continue;
5795 }
5796 auto currentDisplayId = sessionProperty->GetDisplayId();
5797 if (displayId != currentDisplayId) {
5798 continue;
5799 }
5800 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
5801 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
5802 if (isForeground && sceneSession->GetParentSession() != nullptr) {
5803 isForeground = isForeground &&
5804 (sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
5805 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE);
5806 }
5807 bool isPrivate = sessionProperty->GetPrivacyMode() ||
5808 sceneSession->GetCombinedExtWindowFlags().privacyModeFlag;
5809 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
5810 if ((isForeground || IsSystemWindowVisible) && isPrivate) {
5811 if (!sceneSession->GetSessionInfo().bundleName_.empty()) {
5812 privacyBundles.insert(sceneSession->GetSessionInfo().bundleName_);
5813 } else {
5814 TLOGD(WmsLogTag::WMS_MAIN, "bundle name is empty, wid = %{public}d.", item.first);
5815 privacyBundles.insert(sceneSession->GetWindowName());
5816 }
5817 }
5818 }
5819 }
5820
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5821 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5822 {
5823 NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
5824 this->OnSessionStateChange(persistentId, state);
5825 };
5826 if (sceneSession == nullptr) {
5827 WLOGFE("session is nullptr");
5828 return;
5829 }
5830 sceneSession->SetSessionStateChangeNotifyManagerListener(func);
5831 WLOGFD("RegisterSessionStateChangeFunc success");
5832 }
5833
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)5834 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5835 {
5836 wptr<SceneSessionManager> weakSessionManager = this;
5837 NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
5838 auto sceneSessionManager = weakSessionManager.promote();
5839 if (sceneSessionManager == nullptr) {
5840 return;
5841 }
5842 sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
5843 };
5844 if (sceneSession == nullptr) {
5845 WLOGFE("session is nullptr");
5846 return;
5847 }
5848 sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
5849 }
5850
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)5851 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5852 {
5853 NotifyRequestFocusStatusNotifyManagerFunc func =
5854 [this](int32_t persistentId, const bool isFocused, const bool byForeground, FocusChangeReason reason) {
5855 this->RequestFocusStatus(persistentId, isFocused, byForeground, reason);
5856 };
5857 if (sceneSession == nullptr) {
5858 WLOGFE("session is nullptr");
5859 return;
5860 }
5861 sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
5862 WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
5863 }
5864
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)5865 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
5866 {
5867 GetStateFromManagerFunc func = [this](const ManagerState key) {
5868 switch (key)
5869 {
5870 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
5871 return this->IsScreenLocked();
5872 break;
5873 default:
5874 return false;
5875 break;
5876 }
5877 };
5878 if (sceneSession == nullptr) {
5879 WLOGFE("session is nullptr");
5880 return;
5881 }
5882 sceneSession->SetGetStateFromManagerListener(func);
5883 WLOGFD("RegisterGetStateFromManagerFunc success");
5884 }
5885
RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession> & sceneSession)5886 void SceneSessionManager::RegisterSessionChangeByActionNotifyManagerFunc(sptr<SceneSession>& sceneSession)
5887 {
5888 SessionChangeByActionNotifyManagerFunc func = [this](const sptr<SceneSession>& sceneSession,
5889 const sptr<WindowSessionProperty>& property, WSPropertyChangeAction action) {
5890 if (sceneSession == nullptr || property == nullptr) {
5891 TLOGE(WmsLogTag::DEFAULT, "params is nullptr");
5892 return;
5893 }
5894 switch (action) {
5895 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON:
5896 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
5897 break;
5898 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE:
5899 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE:
5900 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS:
5901 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS:
5902 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS:
5903 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS:
5904 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5905 break;
5906 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS:
5907 SetBrightness(sceneSession, property->GetBrightness());
5908 break;
5909 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE:
5910 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE:
5911 UpdatePrivateStateAndNotify(property->GetPersistentId());
5912 break;
5913 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS:
5914 CheckAndNotifyWaterMarkChangedResult();
5915 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5916 break;
5917 case WSPropertyChangeAction::ACTION_UPDATE_MODE:
5918 if (sceneSession->GetSessionProperty() != nullptr) {
5919 ProcessWindowModeType();
5920 }
5921 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
5922 break;
5923 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS:
5924 HandleHideNonSystemFloatingWindows(property, sceneSession);
5925 break;
5926 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_MASK:
5927 FlushWindowInfoToMMI();
5928 break;
5929 default:
5930 break;
5931 }
5932 };
5933 if (sceneSession != nullptr) {
5934 sceneSession->SetSessionChangeByActionNotifyManagerListener(func);
5935 }
5936 }
5937
OnSessionStateChange(int32_t persistentId,const SessionState & state)5938 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
5939 int32_t persistentId, const SessionState& state)
5940 {
5941 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
5942 WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
5943 auto sceneSession = GetSceneSession(persistentId);
5944 if (sceneSession == nullptr) {
5945 WLOGFD("session is nullptr");
5946 return;
5947 }
5948 switch (state) {
5949 case SessionState::STATE_FOREGROUND:
5950 ProcessFocusWhenForeground(sceneSession);
5951 if (!IsSessionVisibleForeground(sceneSession)) {
5952 sceneSession->SetPostProcessProperty(true);
5953 break;
5954 }
5955 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
5956 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
5957 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
5958 UpdatePrivateStateAndNotify(persistentId);
5959 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5960 ProcessSubSessionForeground(sceneSession);
5961 }
5962 break;
5963 case SessionState::STATE_BACKGROUND:
5964 NotifySessionUpdate(sceneSession->GetSessionInfo(), ActionType::SINGLE_BACKGROUND);
5965 RequestSessionUnfocus(persistentId, FocusChangeReason::APP_BACKGROUND);
5966 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
5967 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
5968 HandleKeepScreenOn(sceneSession, false);
5969 UpdatePrivateStateAndNotify(persistentId);
5970 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5971 ProcessSubSessionBackground(sceneSession);
5972 }
5973 break;
5974 default:
5975 break;
5976 }
5977 ProcessWindowModeType();
5978 }
5979
ProcessFocusWhenForeground(sptr<SceneSession> & sceneSession)5980 void SceneSessionManager::ProcessFocusWhenForeground(sptr<SceneSession>& sceneSession)
5981 {
5982 auto persistentId = sceneSession->GetPersistentId();
5983 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
5984 persistentId == focusedSessionId_) {
5985 if (needBlockNotifyFocusStatusUntilForeground_) {
5986 needBlockNotifyUnfocusStatus_ = false;
5987 needBlockNotifyFocusStatusUntilForeground_ = false;
5988 NotifyFocusStatus(sceneSession, true);
5989 }
5990 } else if (!sceneSession->IsFocusedOnShow()) {
5991 sceneSession->SetFocusedOnShow(true);
5992 } else {
5993 if (Session::IsScbCoreEnabled()) {
5994 ProcessFocusWhenForegroundScbCore(sceneSession);
5995 } else {
5996 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5997 }
5998 RequestSessionFocus(persistentId, true, FocusChangeReason::APP_FOREGROUND);
5999 }
6000 }
6001
ProcessFocusWhenForegroundScbCore(sptr<SceneSession> & sceneSession)6002 void SceneSessionManager::ProcessFocusWhenForegroundScbCore(sptr<SceneSession>& sceneSession)
6003 {
6004 if (sceneSession == nullptr) {
6005 TLOGD(WmsLogTag::WMS_FOCUS, "session is nullptr");
6006 return;
6007 }
6008 if (sceneSession->IsFocusableOnShow()) {
6009 if (IsSessionVisibleForeground(sceneSession)) {
6010 RequestSessionFocus(sceneSession->GetPersistentId(), true, FocusChangeReason::APP_FOREGROUND);
6011 } else {
6012 PostProcessFocusState state = {true, true, FocusChangeReason::APP_FOREGROUND};
6013 sceneSession->SetPostProcessFocusState(state);
6014 }
6015 } else {
6016 TLOGD(WmsLogTag::WMS_FOCUS, "win: %{public}d ignore request focus when foreground",
6017 sceneSession->GetPersistentId());
6018 }
6019 }
6020
ProcessWindowModeType()6021 void SceneSessionManager::ProcessWindowModeType()
6022 {
6023 if (isScreenLocked_) {
6024 return;
6025 }
6026 NotifyRSSWindowModeTypeUpdate();
6027 }
6028
IsSmallFoldProduct()6029 static bool IsSmallFoldProduct()
6030 {
6031 static const std::string foldScreenType = system::GetParameter("const.window.foldscreen.type", "");
6032 if (foldScreenType.empty()) {
6033 TLOGE(WmsLogTag::DEFAULT, "foldScreenType is empty");
6034 return false;
6035 }
6036 return foldScreenType[0] == '2';
6037 }
6038
IsInSecondaryScreen(const sptr<SceneSession> & sceneSession)6039 bool SceneSessionManager::IsInSecondaryScreen(const sptr<SceneSession>& sceneSession)
6040 {
6041 auto sessionProperty = sceneSession->GetSessionProperty();
6042 if (sessionProperty == nullptr) {
6043 TLOGE(WmsLogTag::DEFAULT, "sessionProperty is nullptr");
6044 return false;
6045 }
6046 ScreenId defaultScreenId = ScreenSessionManagerClient::GetInstance().GetDefaultScreenId();
6047 return sessionProperty->GetDisplayId() != defaultScreenId;
6048 }
6049
CheckWindowModeType()6050 WindowModeType SceneSessionManager::CheckWindowModeType()
6051 {
6052 bool inSplit = false;
6053 bool inFloating = false;
6054 bool fullScreen = false;
6055 bool isSmallFold = IsSmallFoldProduct();
6056 {
6057 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6058 for (const auto& session : sceneSessionMap_) {
6059 if (session.second == nullptr ||
6060 !WindowHelper::IsMainWindow(session.second->GetWindowType()) ||
6061 !Rosen::SceneSessionManager::GetInstance().IsSessionVisibleForeground(session.second)) {
6062 continue;
6063 }
6064 if (isSmallFold && IsInSecondaryScreen(session.second)) {
6065 continue;
6066 }
6067 auto mode = session.second->GetWindowMode();
6068 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
6069 inSplit = true;
6070 }
6071 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
6072 inFloating = true;
6073 }
6074 if (WindowHelper::IsFullScreenWindow(mode)) {
6075 fullScreen = true;
6076 }
6077 }
6078 }
6079
6080 WindowModeType type;
6081 if (inSplit) {
6082 if (inFloating) {
6083 type = WindowModeType::WINDOW_MODE_SPLIT_FLOATING;
6084 } else {
6085 type = WindowModeType::WINDOW_MODE_SPLIT;
6086 }
6087 } else {
6088 if (inFloating) {
6089 if (fullScreen) {
6090 type = WindowModeType::WINDOW_MODE_FULLSCREEN_FLOATING;
6091 } else {
6092 type = WindowModeType::WINDOW_MODE_FLOATING;
6093 }
6094 } else if (fullScreen) {
6095 type = WindowModeType::WINDOW_MODE_FULLSCREEN;
6096 } else {
6097 type = WindowModeType::WINDOW_MODE_OTHER;
6098 }
6099 }
6100 return type;
6101 }
6102
NotifyRSSWindowModeTypeUpdate()6103 void SceneSessionManager::NotifyRSSWindowModeTypeUpdate()
6104 {
6105 WindowModeType type = CheckWindowModeType();
6106 if (lastWindowModeType_ == type) {
6107 return;
6108 }
6109 lastWindowModeType_ = type;
6110 TLOGI(WmsLogTag::WMS_MAIN, "Notify RSS Window Mode Type Update, type : %{public}d",
6111 static_cast<uint8_t>(type));
6112 SessionManagerAgentController::GetInstance().UpdateWindowModeTypeInfo(type);
6113 }
6114
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)6115 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
6116 {
6117 if (sceneSession == nullptr) {
6118 WLOGFD("session is nullptr");
6119 return;
6120 }
6121 std::vector<sptr<Session>> modalVec = sceneSession->GetDialogVector();
6122 for (const auto& subSession : sceneSession->GetSubSession()) {
6123 if (subSession == nullptr) {
6124 TLOGD(WmsLogTag::WMS_SUB, "sub session is nullptr");
6125 continue;
6126 }
6127 if (subSession->IsTopmost()) {
6128 modalVec.push_back(subSession);
6129 TLOGD(WmsLogTag::WMS_SUB, "sub session is topmost modal sub window");
6130 continue;
6131 }
6132 const auto& state = subSession->GetSessionState();
6133 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6134 TLOGD(WmsLogTag::WMS_SUB, "sub session is not active");
6135 continue;
6136 }
6137 RequestSessionFocus(subSession->GetPersistentId(), true);
6138 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6139 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
6140 }
6141
6142 for (const auto& modal : modalVec) {
6143 if (modal == nullptr) {
6144 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is nullptr");
6145 continue;
6146 }
6147 const auto& state = modal->GetSessionState();
6148 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6149 TLOGD(WmsLogTag::WMS_DIALOG, "dialog or topmost modal sub window is not active");
6150 continue;
6151 }
6152 auto modalSession = GetSceneSession(modal->GetPersistentId());
6153 if (modalSession == nullptr) {
6154 TLOGD(WmsLogTag::WMS_DIALOG, "modalSession is null");
6155 continue;
6156 }
6157 NotifyWindowInfoChange(modal->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
6158 if (modal->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
6159 needBlockNotifyUnfocusStatus_ = false;
6160 needBlockNotifyFocusStatusUntilForeground_ = false;
6161 NotifyFocusStatus(modalSession, true);
6162 }
6163 HandleKeepScreenOn(modalSession, modalSession->IsKeepScreenOn());
6164 }
6165 }
6166
ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6167 WSError SceneSessionManager::ProcessModalTopmostRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6168 {
6169 // focus must on modal topmost subwindow when APP_MAIN_WINDOW or sub winodw request focus
6170 sptr<SceneSession> mainSession = nullptr;
6171 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6172 mainSession = sceneSession;
6173 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6174 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6175 }
6176 if (mainSession == nullptr) {
6177 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6178 return WSError::WS_DO_NOTHING;
6179 }
6180
6181 std::vector<sptr<SceneSession>> topmostVec;
6182 for (auto subSession : mainSession->GetSubSession()) {
6183 if (subSession && subSession->IsTopmost()) {
6184 topmostVec.push_back(subSession);
6185 }
6186 }
6187 if (std::find_if(topmostVec.begin(), topmostVec.end(),
6188 [this](sptr<SceneSession>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6189 != topmostVec.end()) {
6190 TLOGD(WmsLogTag::WMS_SUB, "modal topmost subwindow id: %{public}d has been focused!", focusedSessionId_);
6191 return WSError::WS_OK;
6192 }
6193 WSError ret = WSError::WS_DO_NOTHING;
6194 for (auto topmostSession : topmostVec) {
6195 if (topmostSession == nullptr) {
6196 continue;
6197 }
6198 // no need to consider order, since rule of zOrder
6199 if (RequestSessionFocusImmediately(topmostSession->GetPersistentId()) == WSError::WS_OK) {
6200 ret = WSError::WS_OK;
6201 }
6202 }
6203 return ret;
6204 }
6205
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)6206 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
6207 {
6208 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
6209 sptr<SceneSession> mainSession = nullptr;
6210 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6211 mainSession = sceneSession;
6212 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
6213 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
6214 }
6215 if (mainSession == nullptr) {
6216 TLOGD(WmsLogTag::WMS_FOCUS, "main window is nullptr");
6217 return WSError::WS_DO_NOTHING;
6218 }
6219 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
6220 if (std::find_if(dialogVec.begin(), dialogVec.end(),
6221 [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
6222 != dialogVec.end()) {
6223 TLOGD(WmsLogTag::WMS_DIALOG, "dialog id: %{public}d has been focused!", focusedSessionId_);
6224 return WSError::WS_OK;
6225 }
6226 WSError ret = WSError::WS_DO_NOTHING;
6227 for (auto dialog : dialogVec) {
6228 if (dialog == nullptr) {
6229 continue;
6230 }
6231 // no need to consider order, since rule of zOrder
6232 if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
6233 ret = WSError::WS_OK;
6234 }
6235 }
6236 return ret;
6237 }
6238
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)6239 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
6240 {
6241 if (sceneSession == nullptr) {
6242 WLOGFD("session is nullptr");
6243 return;
6244 }
6245 for (const auto& subSession : sceneSession->GetSubSession()) {
6246 if (subSession == nullptr) {
6247 WLOGFD("sub session is nullptr");
6248 continue;
6249 }
6250 const auto& state = subSession->GetSessionState();
6251 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6252 WLOGFD("sub session is not active");
6253 continue;
6254 }
6255 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6256 HandleKeepScreenOn(subSession, false);
6257 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
6258 }
6259 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
6260 for (const auto& dialog : dialogVec) {
6261 if (dialog == nullptr) {
6262 TLOGD(WmsLogTag::WMS_DIALOG, "dialog is nullptr");
6263 continue;
6264 }
6265 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
6266 if (dialogSession == nullptr) {
6267 TLOGD(WmsLogTag::WMS_DIALOG, "dialogSession is null");
6268 continue;
6269 }
6270 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6271 HandleKeepScreenOn(dialogSession, false);
6272 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
6273 }
6274 for (const auto& toastSession : sceneSession->GetToastSession()) {
6275 if (toastSession == nullptr) {
6276 TLOGD(WmsLogTag::WMS_TOAST, "toastSession session is nullptr");
6277 continue;
6278 }
6279 const auto& state = toastSession->GetSessionState();
6280 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6281 continue;
6282 }
6283 NotifyWindowInfoChange(toastSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
6284 HandleKeepScreenOn(toastSession, false);
6285 UpdatePrivateStateAndNotify(toastSession->GetPersistentId());
6286 toastSession->SetActive(false);
6287 toastSession->BackgroundTask();
6288 }
6289 }
6290
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)6291 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
6292 const sptr<WindowSessionProperty>& property)
6293 {
6294 if (sceneSession == nullptr) {
6295 WLOGFD("session is nullptr");
6296 return WSError::WS_ERROR_NULLPTR;
6297 }
6298 auto sessionProperty = sceneSession->GetSessionProperty();
6299 if (sessionProperty == nullptr) {
6300 return WSError::WS_ERROR_NULLPTR;
6301 }
6302 uint32_t flags = property->GetWindowFlags();
6303 uint32_t oldFlags = sessionProperty->GetWindowFlags();
6304 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
6305 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
6306 !property->GetSystemCalling()) {
6307 WLOGFE("Set window flags permission denied");
6308 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6309 }
6310 sessionProperty->SetWindowFlags(flags);
6311 CheckAndNotifyWaterMarkChangedResult();
6312 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
6313 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
6314 }
6315 WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
6316 return WSError::WS_OK;
6317 }
6318
CheckAndNotifyWaterMarkChangedResult()6319 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
6320 {
6321 bool currentWaterMarkShowState = false;
6322 {
6323 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6324 for (const auto& iter: sceneSessionMap_) {
6325 auto& session = iter.second;
6326 if (!session) {
6327 continue;
6328 }
6329 auto sessionProperty = session->GetSessionProperty();
6330 if (!sessionProperty) {
6331 continue;
6332 }
6333 bool hasWaterMark = sessionProperty->GetWindowFlags() &
6334 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
6335 bool isExtWindowHasWaterMarkFlag = session->GetCombinedExtWindowFlags().waterMarkFlag;
6336 if ((hasWaterMark && session->GetRSVisible()) || isExtWindowHasWaterMarkFlag) {
6337 currentWaterMarkShowState = true;
6338 break;
6339 }
6340 }
6341 if (combinedExtWindowFlags_.waterMarkFlag) {
6342 TLOGI(WmsLogTag::WMS_UIEXT, "CheckAndNotifyWaterMarkChangedResult scb uiext has water mark");
6343 currentWaterMarkShowState = true;
6344 }
6345 }
6346 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
6347 lastWaterMarkShowState_ = currentWaterMarkShowState;
6348 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
6349 }
6350 }
6351
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)6352 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
6353 {
6354 WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
6355 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
6356 return WSError::WS_OK;
6357 }
6358
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const6359 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo& abilityInfo) const
6360 {
6361 if (!bundleMgr_) {
6362 WLOGFE("bundle manager is nullptr.");
6363 return;
6364 }
6365
6366 AAFwk::Want want;
6367 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
6368 auto uid = abilityInfo.uid;
6369 want.SetParam("uid", uid);
6370 bundleMgr_->ProcessPreload(want);
6371 }
6372
NotifyCompleteFirstFrameDrawing(int32_t persistentId)6373 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
6374 {
6375 auto scnSession = GetSceneSession(persistentId);
6376 if (scnSession == nullptr) {
6377 TLOGE(WmsLogTag::WMS_MAIN, " scnSession is nullptr.");
6378 return;
6379 }
6380
6381 const auto& sessionInfo = scnSession->GetSessionInfo();
6382 if (IsAtomicServiceFreeInstall(sessionInfo)) {
6383 TLOGI(WmsLogTag::WMS_LIFE, "AtomicService free-install start, id: %{public}d, type: %{public}d",
6384 scnSession->GetPersistentId(), scnSession->GetWindowType());
6385 FillSessionInfo(scnSession);
6386 }
6387
6388 TLOGI(WmsLogTag::WMS_MAIN, " id: %{public}d, app info: [%{public}s %{public}s %{public}s]",
6389 scnSession->GetPersistentId(), sessionInfo.bundleName_.c_str(),
6390 sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
6391 auto abilityInfoPtr = sessionInfo.abilityInfo;
6392 if (abilityInfoPtr == nullptr) {
6393 TLOGE(WmsLogTag::WMS_MAIN, " abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
6394 return;
6395 }
6396 if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
6397 !(abilityInfoPtr->excludeFromMissions)) {
6398 WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
6399 listenerController_->NotifySessionCreated(persistentId);
6400 }
6401
6402 if (eventHandler_ != nullptr) {
6403 auto task = [persistentId]() {
6404 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(persistentId);
6405 };
6406 WLOGFI("Post CompleteFirstFrameDrawing task.");
6407 bool ret = eventHandler_->PostTask(task, "wms:CompleteFirstFrameDrawing", 0);
6408 if (!ret) {
6409 WLOGFE("Report post first frame task failed. the task name is CompleteFirstFrameDrawing");
6410 }
6411 }
6412
6413 if (taskScheduler_ == nullptr) {
6414 return;
6415 }
6416 auto task = [this, abilityInfoPtr]() {
6417 ProcessPreload(*abilityInfoPtr);
6418 };
6419 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
6420 }
6421
NotifySessionMovedToFront(int32_t persistentId)6422 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
6423 {
6424 WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
6425 auto scnSession = GetSceneSession(persistentId);
6426 if (scnSession == nullptr) {
6427 WLOGFE("session is invalid with %{public}d", persistentId);
6428 return;
6429 }
6430 WLOGFI("NotifySessionMovedToFront, id: %{public}d, system: %{public}d", scnSession->GetPersistentId(),
6431 scnSession->GetSessionInfo().isSystem_);
6432 if (listenerController_ != nullptr &&
6433 !scnSession->GetSessionInfo().isSystem_ &&
6434 (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
6435 !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6436 listenerController_->NotifySessionMovedToFront(persistentId);
6437 }
6438 }
6439
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)6440 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject>& token, const std::string& label)
6441 {
6442 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
6443 auto task = [this, &token, &label]() {
6444 auto sceneSession = FindSessionByToken(token);
6445 if (sceneSession == nullptr) {
6446 WLOGFI("fail to find session by token");
6447 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6448 }
6449 sceneSession->SetSessionLabel(label);
6450 WLOGFI("NotifySessionLabelUpdated, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6451 sceneSession->GetSessionInfo().isSystem_);
6452 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
6453 WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
6454 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
6455 }
6456 return WSError::WS_OK;
6457 };
6458 return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
6459 }
6460
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)6461 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject>& token,
6462 const std::shared_ptr<Media::PixelMap>& icon)
6463 {
6464 WLOGFI("Enter");
6465 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6466 WLOGFE("The caller is not system-app, can not use system-api");
6467 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6468 }
6469
6470 auto task = [this, &token, &icon]() {
6471 auto sceneSession = FindSessionByToken(token);
6472 if (sceneSession == nullptr) {
6473 WLOGFI("fail to find session by token");
6474 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
6475 }
6476 sceneSession->SetSessionIcon(icon);
6477 WLOGFI("NotifySessionIconChanged, id: %{public}d, system: %{public}d", sceneSession->GetPersistentId(),
6478 sceneSession->GetSessionInfo().isSystem_);
6479 if (listenerController_ != nullptr &&
6480 !sceneSession->GetSessionInfo().isSystem_ &&
6481 (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
6482 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
6483 WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
6484 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
6485 }
6486 return WSError::WS_OK;
6487 };
6488 return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
6489 }
6490
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)6491 WSError SceneSessionManager::IsValidSessionIds(
6492 const std::vector<int32_t>& sessionIds, std::vector<bool>& results)
6493 {
6494 WLOGFI("Enter");
6495 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6496 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
6497 auto search = sceneSessionMap_.find(sessionIds.at(i));
6498 if (search == sceneSessionMap_.end() || search->second == nullptr) {
6499 results.push_back(false);
6500 continue;
6501 }
6502 results.push_back(true);
6503 }
6504 return WSError::WS_OK;
6505 }
6506
RegisterSessionListener(const sptr<ISessionListener> & listener)6507 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
6508 {
6509 WLOGFI("Enter");
6510 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6511 WLOGFE("The caller is not system-app, can not use system-api");
6512 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6513 }
6514 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6515 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6516 return WSError::WS_ERROR_INVALID_PERMISSION;
6517 }
6518 auto task = [this, &listener]() {
6519 WSError ret = WSError::WS_DO_NOTHING;
6520 if (listenerController_ != nullptr) {
6521 ret = listenerController_->AddSessionListener(listener);
6522 } else {
6523 WLOGFE("The listenerController is nullptr");
6524 }
6525
6526 // app continue report for distributed scheduled service
6527 SingletonContainer::Get<DmsReporter>().ReportContinueApp(ret == WSError::WS_OK,
6528 static_cast<int32_t>(ret));
6529
6530 return ret;
6531 };
6532 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
6533 }
6534
UnRegisterSessionListener(const sptr<ISessionListener> & listener)6535 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
6536 {
6537 WLOGFI("Enter");
6538 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6539 WLOGFE("The caller is not system-app, can not use system-api");
6540 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6541 }
6542 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
6543 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
6544 return WSError::WS_ERROR_INVALID_PERMISSION;
6545 }
6546 auto task = [this, &listener]() {
6547 if (listenerController_ != nullptr) {
6548 listenerController_->DelSessionListener(listener);
6549 return WSError::WS_OK;
6550 } else {
6551 WLOGFE("The listenerController is nullptr");
6552 return WSError::WS_DO_NOTHING;
6553 }
6554 };
6555 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
6556 }
6557
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6558 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
6559 std::vector<SessionInfoBean>& sessionInfos)
6560 {
6561 WLOGFI("Enter num max %{public}d", numMax);
6562 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6563 WLOGFE("The caller is not system-app, can not use system-api");
6564 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6565 }
6566 if (!SessionPermission::VerifySessionPermission()) {
6567 WLOGFE("The caller has not permission granted");
6568 return WSError::WS_ERROR_INVALID_PERMISSION;
6569 }
6570 auto task = [this, &deviceId, numMax, &sessionInfos]() {
6571 if (CheckIsRemote(deviceId)) {
6572 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
6573 if (ret != ERR_OK) {
6574 return WSError::WS_ERROR_INVALID_PARAM;
6575 } else {
6576 return WSError::WS_OK;
6577 }
6578 }
6579 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6580 std::vector<sptr<SceneSession>> sceneSessionInfos;
6581 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6582 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
6583 auto sceneSession = iter->second;
6584 if (sceneSession == nullptr) {
6585 WLOGFE("session is nullptr");
6586 continue;
6587 }
6588 auto sessionInfo = sceneSession->GetSessionInfo();
6589 if (sessionInfo.isSystem_) {
6590 WLOGFD("sessionId: %{public}d is SystemScene", sceneSession->GetPersistentId());
6591 continue;
6592 }
6593 auto want = sessionInfo.want;
6594 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
6595 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6596 sceneSession->GetPersistentId());
6597 continue;
6598 }
6599 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
6600 break;
6601 }
6602 WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
6603 sessionInfo.bundleName_.c_str());
6604 sceneSessionInfos.emplace_back(sceneSession);
6605 }
6606 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
6607 };
6608 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
6609 }
6610
GetMainWindowStatesByPid(int32_t pid,std::vector<MainWindowState> & windowStates)6611 WSError SceneSessionManager::GetMainWindowStatesByPid(int32_t pid, std::vector<MainWindowState>& windowStates)
6612 {
6613 TLOGI(WmsLogTag::WMS_LIFE, "pid:%{public}d", pid);
6614 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
6615 TLOGE(WmsLogTag::WMS_LIFE, "Get all mainWindow states failed, only support SA calling.");
6616 return WSError::WS_ERROR_INVALID_PERMISSION;
6617 }
6618 if (pid < 0) {
6619 return WSError::WS_ERROR_INVALID_PARAM;
6620 }
6621 auto task = [this, pid, &windowStates] {
6622 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6623 for (const auto& [_, sceneSession] : sceneSessionMap_) {
6624 if (sceneSession != nullptr && sceneSession->GetCallingPid() == pid &&
6625 WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6626 MainWindowState windowState;
6627 windowState.state_ = static_cast<int32_t>(sceneSession->GetSessionState());
6628 windowState.isVisible_ = sceneSession->GetRSVisible();
6629 windowState.isForegroundInteractive_ = sceneSession->GetForegroundInteractiveStatus();
6630 windowState.isPcOrPadEnableActivation_ = sceneSession->IsPcOrPadEnableActivation();
6631 windowStates.emplace_back(windowState);
6632 }
6633 }
6634 return WSError::WS_OK;
6635 };
6636 return taskScheduler_->PostSyncTask(task, "GetMainWindowStatesByPid");
6637 }
6638
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)6639 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
6640 std::vector<SessionInfoBean>& sessionInfos)
6641 {
6642 TLOGI(WmsLogTag::DEFAULT, "begin");
6643 int result = DistributedClient::GetInstance().GetMissionInfos(deviceId, numMax, sessionInfos);
6644 if (result != ERR_OK) {
6645 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
6646 return result;
6647 }
6648 return ERR_OK;
6649 }
6650
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6651 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
6652 int32_t persistentId, SessionInfoBean& sessionInfo)
6653 {
6654 WLOGFI("id %{public}d", persistentId);
6655 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6656 WLOGFE("The caller is not system-app, can not use system-api");
6657 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6658 }
6659 if (!SessionPermission::VerifySessionPermission()) {
6660 WLOGFE("The caller has not permission granted");
6661 return WSError::WS_ERROR_INVALID_PERMISSION;
6662 }
6663 auto task = [this, &deviceId, persistentId, &sessionInfo]() {
6664 if (CheckIsRemote(deviceId)) {
6665 int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
6666 if (ret != ERR_OK) {
6667 return WSError::WS_ERROR_INVALID_PARAM;
6668 } else {
6669 return WSError::WS_OK;
6670 }
6671 }
6672 std::map<int32_t, sptr<SceneSession>>::iterator iter;
6673 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6674 iter = sceneSessionMap_.find(persistentId);
6675 if (iter != sceneSessionMap_.end()) {
6676 auto sceneSession = iter->second;
6677 if (sceneSession == nullptr) {
6678 WLOGFE("session: %{public}d is nullptr", persistentId);
6679 return WSError::WS_ERROR_INVALID_PARAM;
6680 }
6681 auto sceneSessionInfo = sceneSession->GetSessionInfo();
6682 if (sceneSessionInfo.isSystem_) {
6683 WLOGFD("sessionId: %{public}d isSystemScene", persistentId);
6684 return WSError::WS_ERROR_INVALID_PARAM;
6685 }
6686 auto want = sceneSessionInfo.want;
6687 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
6688 want->GetElement().GetBundleName().empty()) {
6689 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
6690 persistentId);
6691 return WSError::WS_ERROR_INTERNAL_ERROR;
6692 }
6693 WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
6694 sceneSessionInfo.bundleName_.c_str());
6695 return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
6696 } else {
6697 WLOGFW("sessionId: %{public}d not found", persistentId);
6698 return WSError::WS_ERROR_INVALID_PARAM;
6699 }
6700 };
6701 return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
6702 }
6703
GetSessionInfoByContinueSessionId(const std::string & continueSessionId,SessionInfoBean & sessionInfo)6704 WSError SceneSessionManager::GetSessionInfoByContinueSessionId(const std::string& continueSessionId,
6705 SessionInfoBean& sessionInfo)
6706 {
6707 TLOGI(WmsLogTag::WMS_LIFE, "query session info with continueSessionId: %{public}s",
6708 continueSessionId.c_str());
6709 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6710 TLOGE(WmsLogTag::WMS_LIFE, "The interface only support for system service.");
6711 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6712 }
6713 if (!SessionPermission::VerifySessionPermission()) {
6714 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted.");
6715 return WSError::WS_ERROR_INVALID_PERMISSION;
6716 }
6717 auto task = [this, continueSessionId, &sessionInfo]() {
6718 WSError ret = WSError::WS_ERROR_INVALID_SESSION;
6719 {
6720 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6721 for (auto& [persistentId, sceneSession] : sceneSessionMap_) {
6722 if (sceneSession && sceneSession->GetSessionInfo().continueSessionId_ == continueSessionId) {
6723 ret = SceneSessionConverter::ConvertToMissionInfo(sceneSession, sessionInfo);
6724 break;
6725 }
6726 }
6727 }
6728
6729 TLOGI(WmsLogTag::WMS_LIFE, "get session info finished with ret code: %{public}d", ret);
6730 // app continue report for distributed scheduled service
6731 SingletonContainer::Get<DmsReporter>().ReportQuerySessionInfo(ret == WSError::WS_OK,
6732 static_cast<int32_t>(ret));
6733 return ret;
6734 };
6735 return taskScheduler_->PostSyncTask(task, "GetSessionInfoByContinueSessionId");
6736 }
6737
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)6738 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
6739 int32_t persistentId, SessionInfoBean& sessionInfo)
6740 {
6741 WLOGFI("GetRemoteSessionInfoFromDms begin");
6742 std::vector<SessionInfoBean> sessionVector;
6743 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
6744 if (result != ERR_OK) {
6745 return result;
6746 }
6747 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
6748 if (iter->id == persistentId) {
6749 sessionInfo = *iter;
6750 return ERR_OK;
6751 }
6752 }
6753 WLOGFW("missionId not found");
6754 return ERR_INVALID_VALUE;
6755 }
6756
CheckIsRemote(const std::string & deviceId)6757 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
6758 {
6759 if (deviceId.empty()) {
6760 WLOGFI("CheckIsRemote: deviceId is empty.");
6761 return false;
6762 }
6763 std::string localDeviceId;
6764 if (!GetLocalDeviceId(localDeviceId)) {
6765 WLOGFE("CheckIsRemote: get local deviceId failed");
6766 return false;
6767 }
6768 if (localDeviceId == deviceId) {
6769 WLOGFI("CheckIsRemote: deviceId is local.");
6770 return false;
6771 }
6772 WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
6773 return true;
6774 }
6775
GetLocalDeviceId(std::string & localDeviceId)6776 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
6777 {
6778 auto localNode = std::make_unique<NodeBasicInfo>();
6779 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
6780 if (errCode != ERR_OK) {
6781 WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
6782 return false;
6783 }
6784 if (localNode != nullptr) {
6785 localDeviceId = localNode->networkId;
6786 WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
6787 return true;
6788 }
6789 WLOGFE("localDeviceId null");
6790 return false;
6791 }
6792
AnonymizeDeviceId(const std::string & deviceId)6793 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
6794 {
6795 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
6796 return EMPTY_DEVICE_ID;
6797 }
6798 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
6799 anonDeviceId.append("******");
6800 return anonDeviceId;
6801 }
6802
DumpSessionAll(std::vector<std::string> & infos)6803 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string>& infos)
6804 {
6805 WLOGFI("Dump all session.");
6806 if (!SessionPermission::IsSystemCalling()) {
6807 WLOGFE("DumpSessionAll permission denied!");
6808 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6809 }
6810
6811 auto task = [this, &infos]() {
6812 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6813 infos.push_back(dumpInfo);
6814 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6815 for (const auto &item : sceneSessionMap_) {
6816 auto& session = item.second;
6817 if (session) {
6818 session->DumpSessionInfo(infos);
6819 }
6820 }
6821 return WSError::WS_OK;
6822 };
6823
6824 return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
6825 }
6826
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)6827 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string>& infos)
6828 {
6829 WLOGFI("Dump session with id %{public}d", persistentId);
6830 if (!SessionPermission::IsSystemCalling()) {
6831 WLOGFE("DumpSessionWithId permission denied!");
6832 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6833 }
6834
6835 auto task = [this, persistentId, &infos]() {
6836 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
6837 infos.push_back(dumpInfo);
6838 auto session = GetSceneSession(persistentId);
6839 if (session) {
6840 session->DumpSessionInfo(infos);
6841 } else {
6842 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
6843 }
6844 return WSError::WS_OK;
6845 };
6846
6847 return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
6848 }
6849
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6850 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetAllAbilityInfos(
6851 const AAFwk::Want& want, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6852 {
6853 if (bundleMgr_ == nullptr) {
6854 WLOGFE("bundleMgr_ is nullptr");
6855 return WSError::WS_ERROR_NULLPTR;
6856 }
6857 auto elementName = want.GetElement();
6858 int32_t ret{0};
6859 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6860 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6861 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6862 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6863 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6864 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6865 std::vector<AppExecFwk::BundleInfo> bundleInfos;
6866 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
6867 WLOGFD("want is empty queryAllAbilityInfos");
6868 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
6869 if (ret) {
6870 WLOGFE("Query all ability infos from BMS failed!");
6871 return WSError::WS_ERROR_INVALID_PARAM;
6872 }
6873 } else if (!elementName.GetBundleName().empty()) {
6874 AppExecFwk::BundleInfo bundleInfo;
6875 WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
6876 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
6877 if (ret) {
6878 WLOGFE("Query ability info from BMS failed!");
6879 return WSError::WS_ERROR_INVALID_PARAM;
6880 }
6881 bundleInfos.push_back(bundleInfo);
6882 } else {
6883 WLOGFE("invalid want:%{public}s", want.ToString().c_str());
6884 return WSError::WS_ERROR_INVALID_PARAM;
6885 }
6886 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6887 }
6888
GetBatchAbilityInfos(const std::vector<std::string> & bundleNames,int32_t userId,std::vector<SCBAbilityInfo> & scbAbilityInfos)6889 __attribute__((no_sanitize("cfi"))) WSError SceneSessionManager::GetBatchAbilityInfos(
6890 const std::vector<std::string>& bundleNames, int32_t userId, std::vector<SCBAbilityInfo>& scbAbilityInfos)
6891 {
6892 if (bundleMgr_ == nullptr) {
6893 TLOGE(WmsLogTag::DEFAULT, "bundleMgr is nullptr");
6894 return WSError::WS_ERROR_NULLPTR;
6895 }
6896 if (bundleNames.empty()) {
6897 TLOGE(WmsLogTag::DEFAULT, "bundleNames is empty");
6898 return WSError::WS_ERROR_INVALID_PARAM;
6899 }
6900 auto flag = AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6901 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6902 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6903 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6904 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6905 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE);
6906 std::vector<AppExecFwk::BundleInfo> bundleInfos;
6907 auto ret = static_cast<int32_t>(bundleMgr_->BatchGetBundleInfo(bundleNames, flag, bundleInfos, userId));
6908 if (ret) {
6909 TLOGE(WmsLogTag::DEFAULT, "Query batch ability infos from BMS failed!");
6910 return WSError::WS_ERROR_INVALID_PARAM;
6911 }
6912 return GetAbilityInfosFromBundleInfo(bundleInfos, scbAbilityInfos);
6913 }
6914
GetAbilityInfo(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,int32_t userId,SCBAbilityInfo & scbAbilityInfo)6915 WSError SceneSessionManager::GetAbilityInfo(const std::string& bundleName, const std::string& moduleName,
6916 const std::string& abilityName, int32_t userId, SCBAbilityInfo& scbAbilityInfo)
6917 {
6918 if (bundleMgr_ == nullptr) {
6919 TLOGE(WmsLogTag::DEFAULT, "bundleMgr_ is nullptr");
6920 return WSError::WS_ERROR_NULLPTR;
6921 }
6922 auto flags = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
6923 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
6924 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
6925 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
6926 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) |
6927 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
6928 AppExecFwk::BundleInfo bundleInfo;
6929 if (bundleMgr_->GetBundleInfoV9(bundleName, flags, bundleInfo, userId)) {
6930 TLOGE(WmsLogTag::DEFAULT, "Query ability info from BMS failed, ability:%{public}s", abilityName.c_str());
6931 return WSError::WS_ERROR_INVALID_PARAM;
6932 }
6933 auto& hapModulesList = bundleInfo.hapModuleInfos;
6934 if (hapModulesList.empty()) {
6935 TLOGD(WmsLogTag::DEFAULT, "hapModulesList is empty, ability:%{public}s", abilityName.c_str());
6936 return WSError::WS_ERROR_INVALID_PARAM;
6937 }
6938 auto sdkVersion = bundleInfo.targetVersion % 100; // % 100 to get the real version
6939 for (auto& hapModule : hapModulesList) {
6940 auto& abilityInfoList = hapModule.abilityInfos;
6941 for (auto& abilityInfo : abilityInfoList) {
6942 if (abilityInfo.moduleName == moduleName && abilityInfo.name == abilityName) {
6943 scbAbilityInfo.abilityInfo_ = abilityInfo;
6944 scbAbilityInfo.sdkVersion_ = sdkVersion;
6945 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6946 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6947 return WSError::WS_OK;
6948 }
6949 }
6950 }
6951 TLOGW(WmsLogTag::DEFAULT, "Ability info not found, ability:%{public}s", abilityName.c_str());
6952 return WSError::WS_ERROR_INVALID_PARAM;
6953 }
6954
GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<SCBAbilityInfo> & scbAbilityInfos)6955 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(const std::vector<AppExecFwk::BundleInfo>& bundleInfos,
6956 std::vector<SCBAbilityInfo>& scbAbilityInfos)
6957 {
6958 if (bundleInfos.empty()) {
6959 WLOGFE("bundleInfos is empty");
6960 return WSError::WS_ERROR_INVALID_PARAM;
6961 }
6962 for (auto& bundleInfo : bundleInfos) {
6963 auto& hapModulesList = bundleInfo.hapModuleInfos;
6964 auto sdkVersion = bundleInfo.targetVersion % 100; // %100 to get the real version
6965 if (hapModulesList.empty()) {
6966 WLOGFD("hapModulesList is empty");
6967 continue;
6968 }
6969 if (bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE) ||
6970 bundleInfo.applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
6971 auto iter = std::find_if(hapModulesList.begin(), hapModulesList.end(),
6972 [](const AppExecFwk::HapModuleInfo& hapModule) { return !hapModule.abilityInfos.empty(); });
6973 if (iter != hapModulesList.end()) {
6974 SCBAbilityInfo scbAbilityInfo;
6975 scbAbilityInfo.abilityInfo_ = iter->abilityInfos[0];
6976 scbAbilityInfo.sdkVersion_ = sdkVersion;
6977 scbAbilityInfo.codePath_ = bundleInfo.applicationInfo.codePath;
6978 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6979 scbAbilityInfos.push_back(scbAbilityInfo);
6980 continue;
6981 }
6982 }
6983 for (auto& hapModule : hapModulesList) {
6984 auto& abilityInfoList = hapModule.abilityInfos;
6985 for (auto& abilityInfo : abilityInfoList) {
6986 SCBAbilityInfo scbAbilityInfo;
6987 scbAbilityInfo.abilityInfo_ = abilityInfo;
6988 scbAbilityInfo.sdkVersion_ = sdkVersion;
6989 GetOrientationFromResourceManager(scbAbilityInfo.abilityInfo_);
6990 scbAbilityInfos.push_back(scbAbilityInfo);
6991 }
6992 }
6993 }
6994 return WSError::WS_OK;
6995 }
6996
GetOrientationFromResourceManager(AppExecFwk::AbilityInfo & abilityInfo)6997 void SceneSessionManager::GetOrientationFromResourceManager(AppExecFwk::AbilityInfo& abilityInfo)
6998 {
6999 if (abilityInfo.orientationId == 0) {
7000 return;
7001 }
7002 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
7003 if (resConfig == nullptr) {
7004 TLOGE(WmsLogTag::DEFAULT, "resConfig is nullptr.");
7005 return;
7006 }
7007 std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager(
7008 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig));
7009 if (resourceMgr == nullptr) {
7010 TLOGE(WmsLogTag::DEFAULT, "resourceMgr is nullptr.");
7011 return;
7012 }
7013 std::string loadPath = abilityInfo.hapPath.empty() ? abilityInfo.resourcePath : abilityInfo.hapPath;
7014 if (!resourceMgr->AddResource(loadPath.c_str(), Global::Resource::SELECT_STRING)) {
7015 TLOGE(WmsLogTag::DEFAULT, "Add resource %{private}s failed.", loadPath.c_str());
7016 }
7017 std::string orientation;
7018 auto ret = resourceMgr->GetStringById(abilityInfo.orientationId, orientation);
7019 if (ret != Global::Resource::RState::SUCCESS) {
7020 TLOGE(WmsLogTag::DEFAULT, "GetStringById failed errcode:%{public}d, labelId:%{public}d",
7021 static_cast<int32_t>(ret), abilityInfo.orientationId);
7022 return;
7023 }
7024 if (STRING_TO_DISPLAY_ORIENTATION_MAP.find(orientation) == STRING_TO_DISPLAY_ORIENTATION_MAP.end()) {
7025 TLOGE(WmsLogTag::DEFAULT, "Do not support this orientation:%{public}s", orientation.c_str());
7026 return;
7027 }
7028 abilityInfo.orientation = STRING_TO_DISPLAY_ORIENTATION_MAP.at(orientation);
7029 }
7030
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller,bool isFromBroker)7031 WSError SceneSessionManager::TerminateSessionNew(
7032 const sptr<AAFwk::SessionInfo> info, bool needStartCaller, bool isFromBroker)
7033 {
7034 if (info == nullptr) {
7035 TLOGI(WmsLogTag::WMS_LIFE, "sessionInfo is nullptr.");
7036 return WSError::WS_ERROR_INVALID_PARAM;
7037 }
7038 TLOGI(WmsLogTag::WMS_LIFE,
7039 "id:%{public}d bundleName:%{public}s needStartCaller:%{public}d isFromBroker:%{public}d",
7040 info->persistentId, info->want.GetElement().GetBundleName().c_str(), needStartCaller, isFromBroker);
7041 int32_t callingPid = IPCSkeleton::GetCallingPid();
7042 uint32_t callerToken = IPCSkeleton::GetCallingTokenID();
7043 auto task = [this, info, needStartCaller, isFromBroker, callingPid, callerToken]() {
7044 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
7045 if (sceneSession == nullptr) {
7046 TLOGE(WmsLogTag::WMS_LIFE, "TerminateSessionNew:fail to find session by token.");
7047 return WSError::WS_ERROR_INVALID_PARAM;
7048 }
7049 const bool pidCheck = (callingPid != -1) && (callingPid == sceneSession->GetCallingPid());
7050 if (!pidCheck &&
7051 !SessionPermission::VerifyPermissionByCallerToken(callerToken,
7052 PermissionConstants::PERMISSION_MANAGE_MISSION)) {
7053 TLOGE(WmsLogTag::WMS_LIFE,
7054 "The caller has not permission granted, callingPid_:%{public}d, callingPid:%{public}d",
7055 sceneSession->GetCallingPid(), callingPid);
7056 return WSError::WS_ERROR_INVALID_PERMISSION;
7057 }
7058 WSError errCode = sceneSession->TerminateSessionNew(info, needStartCaller, isFromBroker);
7059 return errCode;
7060 };
7061 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
7062 }
7063
SetVmaCacheStatus(bool flag)7064 WSError SceneSessionManager::SetVmaCacheStatus(bool flag)
7065 {
7066 WLOGFI("flag: %{public}d", flag);
7067 RSInterfaces::GetInstance().SetVmaCacheStatus(flag);
7068 return WSError::WS_OK;
7069 }
7070
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)7071 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
7072 SessionSnapshot& snapshot, bool isLowResolution)
7073 {
7074 WLOGFI("id: %{public}d isLowResolution: %{public}d", persistentId, isLowResolution);
7075 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
7076 WLOGFE("The caller is not system-app, can not use system-api");
7077 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7078 }
7079 if (!SessionPermission::VerifySessionPermission()) {
7080 WLOGFE("The caller has not permission granted");
7081 return WSError::WS_ERROR_INVALID_PERMISSION;
7082 }
7083 auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
7084 if (CheckIsRemote(deviceId)) {
7085 int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
7086 if (ret != ERR_OK) {
7087 return WSError::WS_ERROR_INVALID_PARAM;
7088 } else {
7089 return WSError::WS_OK;
7090 }
7091 }
7092 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7093 if (!sceneSession) {
7094 return WSError::WS_ERROR_INVALID_PARAM;
7095 }
7096 auto sessionInfo = sceneSession->GetSessionInfo();
7097 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7098 WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7099 sceneSession->GetPersistentId());
7100 }
7101 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
7102 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
7103 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
7104 auto oriSnapshot = sceneSession->Snapshot();
7105 if (oriSnapshot != nullptr) {
7106 if (isLowResolution) {
7107 OHOS::Media::InitializationOptions options;
7108 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
7109 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
7110 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap
7111 = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
7112 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
7113 } else {
7114 snapshot.snapshot = oriSnapshot;
7115 }
7116 }
7117 return WSError::WS_OK;
7118 };
7119 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
7120 }
7121
GetSessionSnapshotById(int32_t persistentId,SessionSnapshot & snapshot)7122 WMError SceneSessionManager::GetSessionSnapshotById(int32_t persistentId, SessionSnapshot& snapshot)
7123 {
7124 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI() && !SessionPermission::IsShellCall()) {
7125 TLOGW(WmsLogTag::WMS_SYSTEM, "Get snapshot failed, Get snapshot by id must be system app!");
7126 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7127 }
7128 auto task = [this, persistentId, &snapshot]() {
7129 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7130 if (!sceneSession) {
7131 TLOGW(WmsLogTag::WMS_SYSTEM, "fail to find session by persistentId: %{public}d", persistentId);
7132 return WMError::WM_ERROR_INVALID_PARAM;
7133 }
7134 auto sessionInfo = sceneSession->GetSessionInfo();
7135 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
7136 TLOGW(WmsLogTag::WMS_SYSTEM, "sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
7137 sceneSession->GetPersistentId());
7138 }
7139 snapshot.topAbility.SetBundleName(sessionInfo.bundleName_.c_str());
7140 snapshot.topAbility.SetModuleName(sessionInfo.moduleName_.c_str());
7141 snapshot.topAbility.SetAbilityName(sessionInfo.abilityName_.c_str());
7142 float snapShotScale = sceneSession->GetFloatingScale() > 1.0f ? 1.0f : sceneSession->GetFloatingScale();
7143 auto oriSnapshot = sceneSession->Snapshot(false, snapShotScale);
7144 if (oriSnapshot != nullptr) {
7145 if (sceneSession->GetFloatingScale() > 1.0f) {
7146 oriSnapshot->scale(sceneSession->GetFloatingScale(), sceneSession->GetFloatingScale());
7147 }
7148 snapshot.snapshot = oriSnapshot;
7149 TLOGI(WmsLogTag::WMS_SYSTEM, "snapshot WxH = %{public}dx%{public}d",
7150 oriSnapshot->GetWidth(), oriSnapshot->GetHeight());
7151 return WMError::WM_OK;
7152 }
7153 return WMError::WM_ERROR_NULLPTR;
7154 };
7155 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotById");
7156 }
7157
GetUIContentRemoteObj(int32_t persistentId,sptr<IRemoteObject> & uiContentRemoteObj)7158 WSError SceneSessionManager::GetUIContentRemoteObj(int32_t persistentId, sptr<IRemoteObject>& uiContentRemoteObj)
7159 {
7160 if (!SessionPermission::IsSACalling()) {
7161 TLOGE(WmsLogTag::DEFAULT, "Permission denied!");
7162 return WSError::WS_ERROR_INVALID_PERMISSION;
7163 }
7164 TLOGI(WmsLogTag::DEFAULT, "PersistentId=%{public}d", persistentId);
7165 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7166 if (sceneSession == nullptr) {
7167 TLOGE(WmsLogTag::DEFAULT, "sceneSession is nullptr");
7168 return WSError::WS_ERROR_NULLPTR;
7169 }
7170 return sceneSession->GetUIContentRemoteObj(uiContentRemoteObj);
7171 }
7172
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)7173 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
7174 AAFwk::MissionSnapshot& sessionSnapshot)
7175 {
7176 TLOGI(WmsLogTag::DEFAULT, "begin");
7177 int result = DistributedClient::GetInstance().GetRemoteMissionSnapshotInfo(deviceId,
7178 sessionId, sessionSnapshot);
7179 if (result != ERR_OK) {
7180 TLOGE(WmsLogTag::DEFAULT, "failed, result = %{public}d", result);
7181 return result;
7182 }
7183 return ERR_OK;
7184 }
7185
GetCollaboratorByType(int32_t collaboratorType)7186 sptr<AAFwk::IAbilityManagerCollaborator> SceneSessionManager::GetCollaboratorByType(int32_t collaboratorType)
7187 {
7188 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = nullptr;
7189 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
7190 auto iter = collaboratorMap_.find(collaboratorType);
7191 if (iter == collaboratorMap_.end()) {
7192 TLOGE(WmsLogTag::DEFAULT, "Fail to found collaborator with type: %{public}d", collaboratorType);
7193 return collaborator;
7194 }
7195 collaborator = iter->second;
7196 if (collaborator == nullptr) {
7197 TLOGE(WmsLogTag::DEFAULT, "Find collaborator type %{public}d, but value is nullptr!", collaboratorType);
7198 }
7199 return collaborator;
7200 }
7201
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)7202 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
7203 {
7204 wptr<SceneSession> weakSceneSession(sceneSession);
7205 auto task = [this, weakSceneSession]() {
7206 auto scnSession = weakSceneSession.promote();
7207 if (scnSession == nullptr) {
7208 WLOGFE("session is nullptr");
7209 return WSError::WS_ERROR_NULLPTR;
7210 }
7211 auto persistentId = scnSession->GetPersistentId();
7212 if (!GetSceneSession(persistentId)) {
7213 WLOGFE("session is invalid with %{public}d", persistentId);
7214 return WSError::WS_ERROR_INVALID_SESSION;
7215 }
7216 auto sessionInfo = scnSession->GetSessionInfo();
7217 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
7218 if (!abilitySessionInfo) {
7219 TLOGE(WmsLogTag::WMS_MAIN,
7220 "RequestSceneSessionByCall abilitySessionInfo is null, id:%{public}d", persistentId);
7221 return WSError::WS_ERROR_NULLPTR;
7222 }
7223 TLOGI(WmsLogTag::WMS_MAIN, "RequestSceneSessionByCall state:%{public}d, id:%{public}d",
7224 sessionInfo.callState_, persistentId);
7225 bool isColdStart = false;
7226 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo, isColdStart);
7227 if (isColdStart) {
7228 TLOGI(WmsLogTag::WMS_MAIN, "ColdStart, identityToken:%{public}s, bundleName:%{public}s",
7229 abilitySessionInfo->identityToken.c_str(), sessionInfo.bundleName_.c_str());
7230 scnSession->SetClientIdentityToken(abilitySessionInfo->identityToken);
7231 scnSession->ResetSessionConnectState();
7232 }
7233 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
7234 return WSError::WS_OK;
7235 };
7236 std::string taskName = "RequestSceneSessionByCall:PID:" +
7237 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
7238 taskScheduler_->PostAsyncTask(task, taskName);
7239 return WSError::WS_OK;
7240 }
7241
StartAbilityBySpecified(const SessionInfo & sessionInfo)7242 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
7243 {
7244 auto task = [this, sessionInfo]() {
7245 WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
7246 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
7247 AAFwk::Want want;
7248 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
7249 if (sessionInfo.want != nullptr) {
7250 want.SetParams(sessionInfo.want->GetParams());
7251 }
7252 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
7253 };
7254
7255 taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
7256 }
7257
NotifyWindowStateErrorFromMMI(int32_t pid,int32_t persistentId)7258 void SceneSessionManager::NotifyWindowStateErrorFromMMI(int32_t pid, int32_t persistentId)
7259 {
7260 TLOGI(WmsLogTag::WMS_LIFE, "pid: %{public}d, persistentId: %{public}d", pid, persistentId);
7261 if (pid == -1) {
7262 TLOGE(WmsLogTag::WMS_LIFE, "invalid pid");
7263 return;
7264 }
7265 int32_t ret = HiSysEventWrite(
7266 HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
7267 "WINDOW_STATE_ERROR",
7268 HiviewDFX::HiSysEvent::EventType::FAULT,
7269 "PID", pid,
7270 "PERSISTENT_ID", persistentId);
7271 if (ret != 0) {
7272 TLOGE(WmsLogTag::WMS_LIFE, "write HiSysEvent error, ret: %{public}d", ret);
7273 }
7274 auto task = [this, pid] {
7275 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7276 for (const auto& [_, sceneSession] : sceneSessionMap_) {
7277 if (!sceneSession || pid != sceneSession->GetCallingPid() ||
7278 !WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
7279 continue;
7280 }
7281 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
7282 if (abilitySessionInfo) {
7283 TLOGI(WmsLogTag::WMS_LIFE, "terminate session, persistentId: %{public}d",
7284 abilitySessionInfo->persistentId);
7285 sceneSession->TerminateSessionNew(abilitySessionInfo, false, false);
7286 }
7287 }
7288 };
7289 // delay 2000ms, wait for hidumper
7290 taskScheduler_->PostAsyncTask(task, __func__, 2000);
7291 }
7292
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)7293 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
7294 {
7295 if (!targetToken) {
7296 WLOGFE("Token is null, cannot find main window");
7297 return nullptr;
7298 }
7299
7300 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7301 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
7302 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
7303 if (pair.second->IsTerminated()) {
7304 return false;
7305 }
7306 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7307 return pair.second->GetAbilityToken() == targetToken;
7308 }
7309 return false;
7310 });
7311 if (iter == sceneSessionMap_.end()) {
7312 WLOGFE("Cannot find session");
7313 return nullptr;
7314 }
7315 return iter->second;
7316 }
7317
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)7318 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
7319 {
7320 if (!SessionPermission::IsSystemCalling()) {
7321 TLOGE(WmsLogTag::WMS_DIALOG, "BindDialogSessionTarget permission denied!");
7322 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7323 }
7324 if (targetToken == nullptr) {
7325 TLOGE(WmsLogTag::WMS_DIALOG, "Target token is null");
7326 return WSError::WS_ERROR_NULLPTR;
7327 }
7328
7329 auto task = [this, persistentId, targetToken]() {
7330 auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
7331 if (scnSession == nullptr) {
7332 TLOGE(WmsLogTag::WMS_DIALOG, "Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
7333 return WSError::WS_ERROR_NULLPTR;
7334 }
7335 if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
7336 TLOGE(WmsLogTag::WMS_DIALOG, "Session is not dialog, type:%{public}u", scnSession->GetWindowType());
7337 return WSError::WS_OK;
7338 }
7339 scnSession->dialogTargetToken_ = targetToken;
7340 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
7341 if (parentSession == nullptr) {
7342 scnSession->NotifyDestroy();
7343 return WSError::WS_ERROR_INVALID_PARAM;
7344 }
7345 scnSession->SetParentSession(parentSession);
7346 scnSession->SetParentPersistentId(parentSession->GetPersistentId());
7347 UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
7348 TLOGI(WmsLogTag::WMS_DIALOG, "Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
7349 persistentId, parentSession->GetPersistentId());
7350 return WSError::WS_OK;
7351 };
7352 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
7353 }
7354
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7355 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7356 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7357 {
7358 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds, isBlackList);
7359 }
7360
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds,bool isBlackList)7361 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
7362 std::vector<uint64_t>& surfaceNodeIds, bool isBlackList)
7363 {
7364 auto isSaCall = SessionPermission::IsSACalling();
7365 if (!isSaCall) {
7366 WLOGFE("The interface only support for sa call");
7367 return WMError::WM_ERROR_INVALID_PERMISSION;
7368 }
7369 auto task = [this, &missionIds, &surfaceNodeIds, isBlackList]() {
7370 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7371 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7372 for (auto missionId : missionIds) {
7373 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
7374 if (iter == sceneSessionMap_.end()) {
7375 continue;
7376 }
7377 auto sceneSession = iter->second;
7378 if (sceneSession == nullptr || sceneSession->GetSurfaceNode() == nullptr) {
7379 continue;
7380 }
7381 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
7382 if (isBlackList && sceneSession->GetLeashWinSurfaceNode()) {
7383 surfaceNodeIds.push_back(missionId);
7384 continue;
7385 }
7386 if (sceneSession->GetLeashWinSurfaceNode()) {
7387 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
7388 }
7389 }
7390 return WMError::WM_OK;
7391 };
7392 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
7393 }
7394
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7395 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
7396 const sptr<IWindowManagerAgent>& windowManagerAgent)
7397 {
7398 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7399 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7400 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7401 if (!SessionPermission::IsSystemCalling()) {
7402 WLOGFE("RegisterWindowManagerAgent permission denied!");
7403 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7404 }
7405 } else if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE) {
7406 if (!SessionPermission::IsSystemServiceCalling()) {
7407 return WMError::WM_ERROR_INVALID_PERMISSION;
7408 }
7409 }
7410 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7411 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7412 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7413 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7414 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7415 if (!SessionPermission::IsSACalling()) {
7416 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7417 return WMError::WM_ERROR_INVALID_PERMISSION;
7418 }
7419 }
7420 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7421 WLOGFE("windowManagerAgent is null");
7422 return WMError::WM_ERROR_NULLPTR;
7423 }
7424 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7425 auto task = [this, windowManagerAgent, type, callingPid]() {
7426 return SessionManagerAgentController::GetInstance()
7427 .RegisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7428 };
7429 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
7430 }
7431
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)7432 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
7433 const sptr<IWindowManagerAgent>& windowManagerAgent)
7434 {
7435 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
7436 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
7437 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
7438 if (!SessionPermission::IsSystemCalling()) {
7439 WLOGFE("UnregisterWindowManagerAgent permission denied!");
7440 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7441 }
7442 }
7443 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY ||
7444 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_DRAWING_STATE ||
7445 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_VISIBLE_WINDOW_NUM ||
7446 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS ||
7447 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_MODE) {
7448 if (!SessionPermission::IsSACalling()) {
7449 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
7450 return WMError::WM_ERROR_INVALID_PERMISSION;
7451 }
7452 }
7453 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
7454 WLOGFE("windowManagerAgent is null");
7455 return WMError::WM_ERROR_NULLPTR;
7456 }
7457 const auto callingPid = IPCSkeleton::GetCallingRealPid();
7458 auto task = [this, windowManagerAgent, type, callingPid]() {
7459 return SessionManagerAgentController::GetInstance()
7460 .UnregisterWindowManagerAgent(windowManagerAgent, type, callingPid);
7461 };
7462 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
7463 }
7464
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)7465 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
7466 {
7467 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
7468 }
7469
UpdateCameraWindowStatus(uint32_t accessTokenId,bool isShowing)7470 void SceneSessionManager::UpdateCameraWindowStatus(uint32_t accessTokenId, bool isShowing)
7471 {
7472 SessionManagerAgentController::GetInstance().UpdateCameraWindowStatus(accessTokenId, isShowing);
7473 }
7474
StartWindowInfoReportLoop()7475 void SceneSessionManager::StartWindowInfoReportLoop()
7476 {
7477 WLOGFD("Report loop");
7478 if (eventHandler_ == nullptr) {
7479 WLOGFE("Report event null");
7480 return ;
7481 }
7482 if (isReportTaskStart_) {
7483 WLOGFE("Report is ReportTask Start");
7484 return;
7485 }
7486 auto task = [this]() {
7487 WindowInfoReporter::GetInstance().ReportRecordedInfos();
7488 ReportWindowProfileInfos();
7489 isReportTaskStart_ = false;
7490 StartWindowInfoReportLoop();
7491 };
7492 int64_t delayTime = 1000 * 60 * 60; // an hour.
7493 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
7494 if (!ret) {
7495 WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
7496 return;
7497 }
7498 isReportTaskStart_ = true;
7499 }
7500
InitPersistentStorage()7501 void SceneSessionManager::InitPersistentStorage()
7502 {
7503 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
7504 int32_t storageMode = -1;
7505 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
7506 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
7507 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
7508 WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
7509 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
7510 }
7511 }
7512 }
7513
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)7514 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
7515 {
7516 WLOGFD("Called.");
7517 if (!SessionPermission::IsSystemServiceCalling()) {
7518 WLOGFE("Only support for system service.");
7519 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7520 }
7521 auto task = [this, &infos]() {
7522 std::map<int32_t, sptr<SceneSession>>::iterator iter;
7523 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7524 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
7525 sptr<SceneSession> sceneSession = iter->second;
7526 if (sceneSession == nullptr) {
7527 WLOGFW("null scene session");
7528 continue;
7529 }
7530 bool isVisibleForAccessibility = Session::IsScbCoreEnabled() ?
7531 sceneSession->IsVisibleForAccessibility() :
7532 sceneSession->IsVisibleForAccessibility() && IsSessionVisibleForeground(sceneSession);
7533 WLOGFD("name=%{public}s, isSystem=%{public}d, persistentId=%{public}d, winType=%{public}d, "
7534 "state=%{public}d, visible=%{public}d", sceneSession->GetWindowName().c_str(),
7535 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
7536 sceneSession->GetSessionState(), isVisibleForAccessibility);
7537 if (isVisibleForAccessibility) {
7538 FillWindowInfo(infos, iter->second);
7539 }
7540 }
7541 return WMError::WM_OK;
7542 };
7543 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
7544 }
7545
CheckUnreliableWindowType(WindowType windowType)7546 static bool CheckUnreliableWindowType(WindowType windowType)
7547 {
7548 if (windowType == WindowType::WINDOW_TYPE_APP_SUB_WINDOW ||
7549 windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
7550 windowType == WindowType::WINDOW_TYPE_TOAST) {
7551 return true;
7552 }
7553 TLOGD(WmsLogTag::DEFAULT, "false, WindowType = %{public}d", windowType);
7554 return false;
7555 }
7556
FillUnreliableWindowInfo(const sptr<SceneSession> & sceneSession,std::vector<sptr<UnreliableWindowInfo>> & infos)7557 static void FillUnreliableWindowInfo(const sptr<SceneSession>& sceneSession,
7558 std::vector<sptr<UnreliableWindowInfo>>& infos)
7559 {
7560 if (sceneSession == nullptr) {
7561 TLOGW(WmsLogTag::DEFAULT, "null scene session.");
7562 return;
7563 }
7564 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7565 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7566 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7567 TLOGD(WmsLogTag::DEFAULT, "filter gesture window.");
7568 return;
7569 }
7570 sptr<UnreliableWindowInfo> info = new (std::nothrow) UnreliableWindowInfo();
7571 if (info == nullptr) {
7572 TLOGE(WmsLogTag::DEFAULT, "null info.");
7573 return;
7574 }
7575 info->windowId_ = sceneSession->GetPersistentId();
7576 WSRect windowRect = sceneSession->GetSessionRect();
7577 info->windowRect_ = { windowRect.posX_, windowRect.posY_, windowRect.width_, windowRect.height_ };
7578 info->zOrder_ = sceneSession->GetZOrder();
7579 info->floatingScale_ = sceneSession->GetFloatingScale();
7580 info->scaleX_ = sceneSession->GetScaleX();
7581 info->scaleY_ = sceneSession->GetScaleY();
7582 infos.emplace_back(info);
7583 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d", info->windowId_);
7584 }
7585
GetUnreliableWindowInfo(int32_t windowId,std::vector<sptr<UnreliableWindowInfo>> & infos)7586 WMError SceneSessionManager::GetUnreliableWindowInfo(int32_t windowId,
7587 std::vector<sptr<UnreliableWindowInfo>>& infos)
7588 {
7589 TLOGD(WmsLogTag::DEFAULT, "Called.");
7590 if (!SessionPermission::IsSystemServiceCalling()) {
7591 TLOGE(WmsLogTag::DEFAULT, "only support for system service.");
7592 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7593 }
7594 auto task = [this, windowId, &infos]() {
7595 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7596 for (const auto& [sessionId, sceneSession] : sceneSessionMap_) {
7597 if (sceneSession == nullptr) {
7598 TLOGW(WmsLogTag::DEFAULT, "null scene session");
7599 continue;
7600 }
7601 if (sessionId == windowId) {
7602 TLOGI(WmsLogTag::DEFAULT, "persistentId: %{public}d is parameter chosen", sessionId);
7603 FillUnreliableWindowInfo(sceneSession, infos);
7604 continue;
7605 }
7606 if (!sceneSession->GetRSVisible()) {
7607 TLOGD(WmsLogTag::DEFAULT, "persistentId: %{public}d is not visible", sessionId);
7608 continue;
7609 }
7610 TLOGD(WmsLogTag::DEFAULT, "name = %{public}s, isSystem = %{public}d, "
7611 "persistentId = %{public}d, winType = %{public}d, state = %{public}d, visible = %{public}d",
7612 sceneSession->GetWindowName().c_str(), sceneSession->GetSessionInfo().isSystem_, sessionId,
7613 sceneSession->GetWindowType(), sceneSession->GetSessionState(), sceneSession->GetRSVisible());
7614 if (CheckUnreliableWindowType(sceneSession->GetWindowType())) {
7615 TLOGI(WmsLogTag::DEFAULT, "persistentId = %{public}d, "
7616 "WindowType = %{public}d", sessionId, sceneSession->GetWindowType());
7617 FillUnreliableWindowInfo(sceneSession, infos);
7618 }
7619 }
7620 return WMError::WM_OK;
7621 };
7622 return taskScheduler_->PostSyncTask(task, "GetUnreliableWindowInfo");
7623 }
7624
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)7625 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
7626 {
7627 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
7628 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
7629 if (sceneSession == nullptr) {
7630 WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
7631 return;
7632 }
7633 wptr<SceneSession> weakSceneSession(sceneSession);
7634 if (processingFlushUIParams_.load()) {
7635 TLOGD(WmsLogTag::WMS_PIPELINE, "Processing flush, notify later.");
7636 auto task = [this, weakSceneSession, type]() {
7637 auto sceneSession = weakSceneSession.promote();
7638 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7639 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7640 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7641 }
7642 };
7643 taskScheduler_->PostAsyncTask(task, "WindowChangeFunc:id:" + std::to_string(persistentId));
7644 return;
7645 }
7646 auto task = [this, weakSceneSession, type]() {
7647 auto sceneSession = weakSceneSession.promote();
7648 NotifyAllAccessibilityInfo();
7649 if (WindowChangedFunc_ != nullptr && sceneSession != nullptr &&
7650 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
7651 WindowChangedFunc_(sceneSession->GetPersistentId(), type);
7652 }
7653 };
7654 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:id:" + std::to_string(persistentId));
7655
7656 auto notifySceneInputTask = [weakSceneSession, type]() {
7657 auto sceneSession = weakSceneSession.promote();
7658 if (sceneSession == nullptr) {
7659 return;
7660 }
7661 SceneInputManager::GetInstance().NotifyWindowInfoChange(sceneSession, type);
7662 };
7663 taskScheduler_->PostAsyncTask(notifySceneInputTask);
7664 }
7665
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)7666 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
7667 const sptr<SceneSession>& sceneSession)
7668 {
7669 if (sceneSession == nullptr) {
7670 WLOGFW("null scene session.");
7671 return false;
7672 }
7673 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
7674 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
7675 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
7676 WLOGFD("filter gesture window.");
7677 return false;
7678 }
7679 sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
7680 if (info == nullptr) {
7681 WLOGFE("null info.");
7682 return false;
7683 }
7684 if (sceneSession->GetSessionInfo().isSystem_) {
7685 info->wid_ = 1;
7686 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7687 } else {
7688 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
7689 }
7690 info->uiNodeId_ = sceneSession->GetUINodeId();
7691 WSRect wsrect = sceneSession->GetSessionGlobalRect(); // only accessability and mmi need global
7692 info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
7693 info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
7694 info->type_ = sceneSession->GetWindowType();
7695 info->mode_ = sceneSession->GetWindowMode();
7696 info->layer_ = sceneSession->GetZOrder();
7697 info->scaleVal_ = sceneSession->GetFloatingScale();
7698 info->scaleX_ = sceneSession->GetScaleX();
7699 info->scaleY_ = sceneSession->GetScaleY();
7700 info->bundleName_ = sceneSession->GetSessionInfo().bundleName_;
7701 info->touchHotAreas_ = sceneSession->GetTouchHotAreas();
7702 auto property = sceneSession->GetSessionProperty();
7703 if (property != nullptr) {
7704 info->displayId_ = property->GetDisplayId();
7705 info->isDecorEnable_ = property->IsDecorEnable();
7706 }
7707 infos.emplace_back(info);
7708 TLOGD(WmsLogTag::WMS_MAIN, "wid = %{public}d, inWid = %{public}d, uiNId = %{public}d, bundleName = %{public}s",
7709 info->wid_, info->innerWid_, info->uiNodeId_, info->bundleName_.c_str());
7710 return true;
7711 }
7712
GetSessionSnapshotFilePath(int32_t persistentId)7713 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
7714 {
7715 WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
7716 auto sceneSession = GetSceneSession(persistentId);
7717 if (sceneSession == nullptr) {
7718 WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
7719 return "";
7720 }
7721 wptr<SceneSession> weakSceneSession(sceneSession);
7722 auto task = [this, weakSceneSession]() {
7723 auto scnSession = weakSceneSession.promote();
7724 if (scnSession == nullptr) {
7725 WLOGFE("session is nullptr");
7726 return std::string("");
7727 }
7728 std::string filePath = scnSession->GetSessionSnapshotFilePath();
7729 return filePath;
7730 };
7731 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
7732 }
7733
SelectSesssionFromMap(const uint64_t & surfaceId)7734 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
7735 {
7736 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7737 for (const auto &item : sceneSessionMap_) {
7738 auto sceneSession = item.second;
7739 if (sceneSession == nullptr) {
7740 continue;
7741 }
7742 if (sceneSession->GetSurfaceNode() == nullptr) {
7743 continue;
7744 }
7745 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
7746 return sceneSession;
7747 }
7748 }
7749 return nullptr;
7750 }
7751
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)7752 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
7753 {
7754 WLOGFD("WindowLayerInfoChangeCallback: entry");
7755 std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
7756
7757 auto task = [this, weak]() {
7758 auto weakOcclusionData = weak.lock();
7759 if (weakOcclusionData == nullptr) {
7760 WLOGFE("weak occlusionData is nullptr");
7761 return;
7762 }
7763 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
7764 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
7765 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
7766 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
7767 if (currVisibleData.size() != 0) {
7768 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
7769 }
7770 if (visibilityChangeInfos.size() != 0) {
7771 DealwithVisibilityChange(visibilityChangeInfos, currVisibleData);
7772 CacVisibleWindowNum();
7773 }
7774
7775 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
7776 if (currDrawingContentData.size() != 0) {
7777 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
7778 }
7779 if (drawingContentChangeInfos.size() != 0) {
7780 DealwithDrawingContentChange(drawingContentChangeInfos);
7781 }
7782 };
7783 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
7784 }
7785
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)7786 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
7787 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
7788 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
7789 {
7790 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
7791 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
7792 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
7793 switch (windowLayerState) {
7794 case WINDOW_ALL_VISIBLE:
7795 case WINDOW_SEMI_VISIBLE:
7796 case WINDOW_IN_VISIBLE:
7797 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
7798 break;
7799 case WINDOW_LAYER_DRAWING:
7800 currDrawingContentData.emplace_back(iter->first, true);
7801 break;
7802 case WINDOW_LAYER_NO_DRAWING:
7803 currDrawingContentData.emplace_back(iter->first, false);
7804 break;
7805 default:
7806 break;
7807 }
7808 }
7809 }
7810
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)7811 void SceneSessionManager::UpdateSubWindowVisibility(const sptr<SceneSession>& session,
7812 WindowVisibilityState visibleState,
7813 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7814 std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos, std::string& visibilityInfo,
7815 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7816 {
7817 if (WindowHelper::IsMainWindow(session->GetWindowType()) &&
7818 visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7819 auto subSessions = GetSubSceneSession(session->GetWindowId());
7820 if (subSessions.empty()) {
7821 return;
7822 }
7823
7824 RemoveDuplicateSubSession(visibilityChangeInfo, subSessions);
7825
7826 for (const auto& subSession : subSessions) {
7827 if (subSession == nullptr) {
7828 continue;
7829 }
7830 if (session->GetCallingPid() != subSession->GetCallingPid() &&
7831 (subSession->IsSessionForeground() || GetSessionRSVisible(subSession, currVisibleData))) {
7832 TLOGI(WmsLogTag::DEFAULT, "Update subwindow visibility for winId: %{public}d",
7833 subSession->GetWindowId());
7834 SetSessionVisibilityInfo(subSession, visibleState, windowVisibilityInfos, visibilityInfo);
7835 }
7836 }
7837 }
7838 }
7839
GetSessionRSVisible(const sptr<Session> & session,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7840 bool SceneSessionManager::GetSessionRSVisible(const sptr<Session>& session,
7841 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7842 {
7843 bool sessionRSVisible = false;
7844 for (const auto& elem : currVisibleData) {
7845 uint64_t surfaceId = elem.first;
7846 WindowVisibilityState visibleState = elem.second;
7847 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7848 sptr<SceneSession> visibilitySession = SelectSesssionFromMap(surfaceId);
7849 if (visibilitySession == nullptr) {
7850 continue;
7851 }
7852 if (session->GetWindowId() == visibilitySession->GetWindowId()) {
7853 if (isVisible) {
7854 sessionRSVisible = true;
7855 }
7856 break;
7857 }
7858 }
7859 return sessionRSVisible;
7860 }
7861
SetSessionVisibilityInfo(const sptr<SceneSession> & session,WindowVisibilityState visibleState,std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos,std::string & visibilityInfo)7862 void SceneSessionManager::SetSessionVisibilityInfo(const sptr<SceneSession>& session,
7863 WindowVisibilityState visibleState, std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos,
7864 std::string& visibilityInfo)
7865 {
7866 if (session == nullptr) {
7867 TLOGE(WmsLogTag::DEFAULT, "Session is invalid!");
7868 return;
7869 }
7870 session->SetRSVisible(visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7871 session->SetVisibilityState(visibleState);
7872 int32_t windowId = session->GetWindowId();
7873 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
7874 session->NotifyWindowVisibility();
7875 }
7876 windowVisibilityInfos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(
7877 windowId, session->GetCallingPid(), session->GetCallingUid(), visibleState, session->GetWindowType()));
7878
7879 visibilityInfo +=
7880 "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " + std::to_string(visibleState) + "], ";
7881 }
7882
RemoveDuplicateSubSession(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,std::vector<sptr<SceneSession>> & subSessions)7883 void SceneSessionManager::RemoveDuplicateSubSession(
7884 const std::vector<std::pair<uint64_t, WindowVisibilityState>>& visibilityChangeInfo,
7885 std::vector<sptr<SceneSession>>& subSessions)
7886 {
7887 for (const auto& elem : visibilityChangeInfo) {
7888 uint64_t surfaceId = elem.first;
7889 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7890 if (session == nullptr) {
7891 continue;
7892 }
7893 for (auto iterator = subSessions.begin(); iterator != subSessions.end();) {
7894 auto subSession = *iterator;
7895 if (subSession && subSession->GetWindowId() == session->GetWindowId()) {
7896 iterator = subSessions.erase(iterator);
7897 } else {
7898 ++iterator;
7899 }
7900 }
7901 }
7902 }
7903
GetSubSceneSession(int32_t parentWindowId)7904 std::vector<sptr<SceneSession>> SceneSessionManager::GetSubSceneSession(int32_t parentWindowId)
7905 {
7906 std::vector<sptr<SceneSession>> subSessions;
7907 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
7908 for (const auto& iter : sceneSessionMap_) {
7909 auto sceneSession = iter.second;
7910 if (sceneSession == nullptr) {
7911 continue;
7912 }
7913 if (sceneSession->GetParentSession() != nullptr &&
7914 sceneSession->GetParentSession()->GetWindowId() == parentWindowId) {
7915 subSessions.push_back(sceneSession);
7916 }
7917 }
7918 return subSessions;
7919 }
7920
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7921 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
7922 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7923 {
7924 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
7925 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
7926 uint32_t i, j;
7927 i = j = 0;
7928 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
7929 if (lastVisibleData_[i].first < currVisibleData[j].first) {
7930 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7931 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7932 }
7933 i++;
7934 } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
7935 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7936 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7937 }
7938 j++;
7939 } else {
7940 if (lastVisibleData_[i].second != currVisibleData[j].second) {
7941 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7942 }
7943 i++;
7944 j++;
7945 }
7946 }
7947 for (; i < lastVisibleData_.size(); ++i) {
7948 if (lastVisibleData_[i].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7949 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
7950 }
7951 }
7952 for (; j < currVisibleData.size(); ++j) {
7953 if (currVisibleData[j].second != WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION) {
7954 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
7955 }
7956 }
7957 lastVisibleData_ = currVisibleData;
7958 return visibilityChangeInfo;
7959 }
7960
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo,const std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)7961 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
7962 visibilityChangeInfo, const std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
7963 {
7964 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
7965 #ifdef MEMMGR_WINDOW_ENABLE
7966 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
7967 #endif
7968
7969 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
7970 for (const auto& elem : visibilityChangeInfo) {
7971 uint64_t surfaceId = elem.first;
7972 WindowVisibilityState visibleState = elem.second;
7973 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
7974 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7975 if (session == nullptr) {
7976 continue;
7977 }
7978 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
7979 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
7980 if (session->GetParentSession() != nullptr &&
7981 !session->GetParentSession()->IsSessionForeground() &&
7982 !GetSessionRSVisible(session->GetParentSession(), currVisibleData)) {
7983 continue;
7984 }
7985 }
7986 SetSessionVisibilityInfo(session, visibleState, windowVisibilityInfos, visibilityInfo);
7987 UpdateSubWindowVisibility(session, visibleState, visibilityChangeInfo, windowVisibilityInfos, visibilityInfo, currVisibleData);
7988 #ifdef MEMMGR_WINDOW_ENABLE
7989 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
7990 session->GetCallingUid(), isVisible));
7991 #endif
7992 CheckAndNotifyWaterMarkChangedResult();
7993 }
7994 if (windowVisibilityInfos.size() != 0) {
7995 WLOGI("Visibility changed, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
7996 visibilityInfo.c_str());
7997 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
7998 }
7999 #ifdef MEMMGR_WINDOW_ENABLE
8000 if (memMgrWindowInfos.size() != 0) {
8001 WLOGD("Notify memMgrWindowInfos changed start");
8002 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8003 }
8004 #endif
8005 }
8006
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)8007 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
8008 drawingContentChangeInfo)
8009 {
8010 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
8011 for (const auto& elem : drawingContentChangeInfo) {
8012 uint64_t surfaceId = elem.first;
8013 bool drawingState = elem.second;
8014 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
8015 if (session == nullptr) {
8016 continue;
8017 }
8018 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
8019 session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
8020 if (openDebugTrace) {
8021 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
8022 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
8023 }
8024 WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
8025 "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
8026 }
8027 if (windowDrawingContenInfos.size() != 0) {
8028 WLOGFD("Notify WindowDrawingContenInfo changed start");
8029 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
8030 }
8031 }
8032
NotifyAppUseControlList(ControlAppType type,int32_t userId,const std::vector<AppUseControlInfo> & controlList)8033 WSError SceneSessionManager::NotifyAppUseControlList(
8034 ControlAppType type, int32_t userId, const std::vector<AppUseControlInfo>& controlList)
8035 {
8036 TLOGI(WmsLogTag::WMS_LIFE,
8037 "controlApptype: %{public}d userId: %{public}d controlList size: %{public}zu",
8038 static_cast<int>(type), userId, controlList.size());
8039 if (!SessionPermission::IsSACalling()) {
8040 TLOGW(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
8041 return WSError::WS_ERROR_INVALID_PERMISSION;
8042 }
8043 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_WRITE_APP_LOCK)) {
8044 TLOGW(WmsLogTag::WMS_LIFE, "write app lock permission denied");
8045 return WSError::WS_ERROR_INVALID_PERMISSION;
8046 }
8047 if (currentUserId_ != userId) {
8048 if (currentUserId_ != DEFAULT_USERID) {
8049 TLOGW(WmsLogTag::WMS_LIFE, "invalid userId, currentUserId_:%{public}d userId:%{public}d",
8050 currentUserId_.load(), userId);
8051 return WSError::WS_ERROR_INVALID_OPERATION;
8052 }
8053 int32_t userIdByUid = GetUserIdByUid(getuid());
8054 if (userId != userIdByUid) {
8055 TLOGW(WmsLogTag::WMS_LIFE,
8056 "invalid userId, currentUserId_:%{public}d userId:%{public}d GetUserIdByUid:%{public}d",
8057 currentUserId_.load(), userId, userIdByUid);
8058 return WSError::WS_ERROR_INVALID_OPERATION;
8059 }
8060 }
8061 taskScheduler_->PostAsyncTask([this, type, userId, controlList] {
8062 if (notifyAppUseControlListFunc_ != nullptr) {
8063 notifyAppUseControlListFunc_(type, userId, controlList);
8064 }
8065
8066 std::vector<sptr<SceneSession>> mainSessions;
8067 for (const auto& appUseControlInfo : controlList) {
8068 GetMainSessionByBundleNameAndAppIndex(appUseControlInfo.bundleName_, appUseControlInfo.appIndex_, mainSessions);
8069 if (mainSessions.empty()) {
8070 continue;
8071 }
8072 for (const auto& session : mainSessions) {
8073 session->NotifyUpdateAppUseControl(type, appUseControlInfo.isNeedControl_);
8074 }
8075 mainSessions.clear();
8076 }
8077 }, __func__);
8078 return WSError::WS_OK;
8079 }
8080
RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc && func)8081 void SceneSessionManager::RegisterNotifyAppUseControlListCallback(NotifyAppUseControlListFunc&& func)
8082 {
8083 taskScheduler_->PostAsyncTask([this, callback = std::move(func)] {
8084 notifyAppUseControlListFunc_ = std::move(callback);
8085 }, __func__);
8086 }
8087
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)8088 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
8089 std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
8090 {
8091 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
8092 for (const auto& data : currDrawingContentData) {
8093 uint64_t windowId = data.first;
8094 bool currentDrawingContentState = data.second;
8095 int32_t pid = 0;
8096 bool isChange = false;
8097 if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
8098 continue;
8099 } else {
8100 isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
8101 }
8102 if (isChange) {
8103 processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
8104 }
8105 }
8106 return processDrawingContentChangeInfo;
8107 }
8108
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)8109 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
8110 {
8111 bool preWindowDrawingState = true;
8112 sptr<SceneSession> session = SelectSesssionFromMap(windowId);
8113 if (session == nullptr) {
8114 return false;
8115 }
8116 pid = session->GetCallingPid();
8117 preWindowDrawingState = session->GetDrawingContentState();
8118 session->SetDrawingContentState(currentDrawingContentState);
8119 return preWindowDrawingState;
8120 }
8121
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)8122 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
8123 {
8124 bool isChange = true;
8125 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8126 for (const auto& item : sceneSessionMap_) {
8127 auto sceneSession = item.second;
8128 if (sceneSession == nullptr) {
8129 continue;
8130 }
8131 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
8132 windowId != sceneSession->GetSurfaceNode()->GetId()) {
8133 if (sceneSession->GetDrawingContentState()) {
8134 return false;
8135 }
8136 }
8137 }
8138 return isChange;
8139 }
8140
InitWithRenderServiceAdded()8141 void SceneSessionManager::InitWithRenderServiceAdded()
8142 {
8143 auto windowVisibilityChangeCb = [this](std::shared_ptr<RSOcclusionData> occlusiontionData) {
8144 this->WindowLayerInfoChangeCallback(occlusiontionData);
8145 };
8146 WLOGI("RegisterWindowVisibilityChangeCallback");
8147 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
8148 WLOGFE("RegisterWindowVisibilityChangeCallback failed");
8149 }
8150 }
8151
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)8152 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
8153 {
8154 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
8155 WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
8156 return WMError::WM_ERROR_INVALID_PARAM;
8157 }
8158
8159 auto task = [this, sceneType]() {
8160 WLOGFD("Set system animated scene %{public}d.", sceneType);
8161 bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
8162 if (!ret) {
8163 WLOGFE("Set system animated scene failed.");
8164 }
8165 };
8166 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
8167 return WMError::WM_OK;
8168 }
8169
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)8170 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
8171 {
8172 if (!SessionPermission::IsSystemCalling()) {
8173 TLOGE(WmsLogTag::WMS_UIEXT, "permission denied!");
8174 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8175 }
8176 if (pid != IPCSkeleton::GetCallingRealPid() || uid != IPCSkeleton::GetCallingUid()) {
8177 TLOGE(WmsLogTag::WMS_UIEXT, "pid and uid check failed!");
8178 return WSError::WS_ERROR_INVALID_PERMISSION;
8179 }
8180 TLOGI(WmsLogTag::WMS_UIEXT, "visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
8181 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
8182 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8183 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
8184 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
8185 WindowType::WINDOW_TYPE_APP_COMPONENT));
8186 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8187 return WSError::WS_OK;
8188 }
8189
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)8190 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
8191 {
8192 if (sceneSession == nullptr) {
8193 WLOGFE("sceneSession is nullptr!");
8194 return;
8195 }
8196 if (sceneSession->GetRSVisible()) {
8197 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
8198 #ifdef MEMMGR_WINDOW_ENABLE
8199 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
8200 #endif
8201 sceneSession->SetRSVisible(false);
8202 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
8203 sceneSession->ClearExtWindowFlags();
8204 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
8205 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
8206 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
8207 #ifdef MEMMGR_WINDOW_ENABLE
8208 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
8209 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
8210 #endif
8211 WLOGFD("covered status changed window:%{public}u, isVisible:%{public}d",
8212 sceneSession->GetWindowId(), sceneSession->GetRSVisible());
8213 CheckAndNotifyWaterMarkChangedResult();
8214 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
8215 #ifdef MEMMGR_WINDOW_ENABLE
8216 WLOGD("Notify memMgrWindowInfos changed start");
8217 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
8218 #endif
8219 }
8220 }
8221
FindSessionByToken(const sptr<IRemoteObject> & token)8222 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject>& token)
8223 {
8224 if (token == nullptr) {
8225 TLOGW(WmsLogTag::DEFAULT, "token is nullptr");
8226 return nullptr;
8227 }
8228 sptr<SceneSession> session = nullptr;
8229 auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8230 if (pair.second == nullptr) {
8231 return false;
8232 }
8233 return pair.second->GetAbilityToken() == token || pair.second->AsObject() == token;
8234 };
8235 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8236 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8237 if (iter != sceneSessionMap_.end()) {
8238 session = iter->second;
8239 }
8240 return session;
8241 }
8242
FindSessionByAffinity(std::string affinity)8243 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
8244 {
8245 if (affinity.size() == 0) {
8246 WLOGFI("AbilityInfo affinity is empty");
8247 return nullptr;
8248 }
8249 sptr<SceneSession> session = nullptr;
8250 auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
8251 if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
8252 return false;
8253 }
8254 return pair.second->GetSessionInfo().sessionAffinity == affinity;
8255 };
8256 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8257 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
8258 if (iter != sceneSessionMap_.end()) {
8259 session = iter->second;
8260 }
8261 return session;
8262 }
8263
PreloadInLakeApp(const std::string & bundleName)8264 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
8265 {
8266 WLOGFD("Enter name %{public}s", bundleName.c_str());
8267 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(CollaboratorType::RESERVE_TYPE);
8268 if (collaborator != nullptr) {
8269 WLOGFI("NotifyPreloadAbility: %{public}s", bundleName.c_str());
8270 collaborator->NotifyPreloadAbility(bundleName);
8271 }
8272 }
8273
PendingSessionToForeground(const sptr<IRemoteObject> & token)8274 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject>& token)
8275 {
8276 TLOGI(WmsLogTag::DEFAULT, "Session is going to foreground");
8277 auto pid = IPCSkeleton::GetCallingRealPid();
8278 if (!SessionPermission::IsSACalling() && !SessionPermission::CheckCallingIsUserTestMode(pid)) {
8279 TLOGE(WmsLogTag::DEFAULT, "Permission denied for going to foreground!");
8280 return WSError::WS_ERROR_INVALID_PERMISSION;
8281 }
8282
8283 auto task = [this, &token]() {
8284 auto session = FindSessionByToken(token);
8285 if (session != nullptr) {
8286 return session->PendingSessionToForeground();
8287 }
8288 TLOGE(WmsLogTag::DEFAULT, "PendingForeground: fail to find token");
8289 return WSError::WS_ERROR_INVALID_PARAM;
8290 };
8291 return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
8292 }
8293
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token,bool shouldBackToCaller)8294 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject>& token,
8295 bool shouldBackToCaller)
8296 {
8297 auto task = [this, &token, shouldBackToCaller] {
8298 auto session = FindSessionByToken(token);
8299 if (session != nullptr) {
8300 return session->PendingSessionToBackgroundForDelegator(shouldBackToCaller);
8301 }
8302 TLOGNE(WmsLogTag::WMS_LIFE, "fail to find token");
8303 return WSError::WS_ERROR_INVALID_PARAM;
8304 };
8305 return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
8306 }
8307
ClearDisplayStatusBarTemporarilyFlags()8308 void SceneSessionManager::ClearDisplayStatusBarTemporarilyFlags()
8309 {
8310 for (auto persistentId : avoidAreaListenerSessionSet_) {
8311 auto sceneSession = GetSceneSession(persistentId);
8312 if (sceneSession == nullptr) {
8313 continue;
8314 }
8315 sceneSession->SetIsDisplayStatusBarTemporarily(false);
8316 }
8317 }
8318
GetFocusSessionToken(sptr<IRemoteObject> & token)8319 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
8320 {
8321 if (!SessionPermission::IsSACalling()) {
8322 WLOGFE("GetFocusSessionToken permission denied!");
8323 return WSError::WS_ERROR_INVALID_PERMISSION;
8324 }
8325 auto task = [this, &token]() {
8326 WLOGFD("GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
8327 auto sceneSession = GetSceneSession(focusedSessionId_);
8328 if (sceneSession) {
8329 token = sceneSession->GetAbilityToken();
8330 if (token == nullptr) {
8331 WLOGFE("token is nullptr");
8332 return WSError::WS_ERROR_INVALID_PARAM;
8333 }
8334 return WSError::WS_OK;
8335 }
8336 return WSError::WS_ERROR_INVALID_PARAM;
8337 };
8338 return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
8339 }
8340
GetFocusSessionElement(AppExecFwk::ElementName & element)8341 WSError SceneSessionManager::GetFocusSessionElement(AppExecFwk::ElementName& element)
8342 {
8343 AppExecFwk::RunningProcessInfo info;
8344 auto pid = IPCSkeleton::GetCallingRealPid();
8345 DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->GetRunningProcessInfoByPid(pid, info);
8346 if (!info.isTestProcess && !SessionPermission::IsSystemCalling()) {
8347 WLOGFE("GetFocusSessionElement permission denied!");
8348 return WSError::WS_ERROR_INVALID_PERMISSION;
8349 }
8350 auto task = [this, &element]() {
8351 WLOGFD("GetFocusSessionElement with focusedSessionId: %{public}d", focusedSessionId_);
8352 auto sceneSession = GetSceneSession(focusedSessionId_);
8353 if (sceneSession) {
8354 auto sessionInfo = sceneSession->GetSessionInfo();
8355 element = AppExecFwk::ElementName("", sessionInfo.bundleName_,
8356 sessionInfo.abilityName_, sessionInfo.moduleName_);
8357 return WSError::WS_OK;
8358 }
8359 return WSError::WS_ERROR_INVALID_SESSION;
8360 };
8361 return taskScheduler_->PostSyncTask(task, "GetFocusSessionElement");
8362 }
8363
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)8364 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
8365 {
8366 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8367 auto task = [this, persistentId, haveListener, callingPid]() {
8368 TLOGI(WmsLogTag::WMS_IMMS,
8369 "UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
8370 persistentId, haveListener);
8371 auto sceneSession = GetSceneSession(persistentId);
8372 if (sceneSession == nullptr) {
8373 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8374 return WSError::WS_DO_NOTHING;
8375 }
8376 if (callingPid != sceneSession->GetCallingPid()) {
8377 TLOGE(WmsLogTag::WMS_IMMS, "Permission denied, not called by the same process");
8378 return WSError::WS_ERROR_INVALID_PERMISSION;
8379 }
8380 if (haveListener) {
8381 avoidAreaListenerSessionSet_.insert(persistentId);
8382 UpdateAvoidArea(persistentId);
8383 } else {
8384 lastUpdatedAvoidArea_.erase(persistentId);
8385 avoidAreaListenerSessionSet_.erase(persistentId);
8386 }
8387 return WSError::WS_OK;
8388 };
8389 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
8390 }
8391
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const sptr<SceneSession> & sceneSession,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)8392 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
8393 const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
8394 {
8395 if (sceneSession == nullptr) {
8396 TLOGI(WmsLogTag::WMS_IMMS, "scene session null no need update avoid area");
8397 return false;
8398 }
8399 if (lastUpdatedAvoidArea_.find(persistentId) == lastUpdatedAvoidArea_.end()) {
8400 lastUpdatedAvoidArea_[persistentId] = {};
8401 }
8402
8403 bool needUpdate = true;
8404 if (auto iter = lastUpdatedAvoidArea_[persistentId].find(avoidAreaType);
8405 iter != lastUpdatedAvoidArea_[persistentId].end()) {
8406 needUpdate = iter->second != avoidArea;
8407 } else {
8408 if (avoidArea.isEmptyAvoidArea()) {
8409 TLOGI(WmsLogTag::WMS_IMMS, "window %{public}d type %{public}d empty avoid area",
8410 persistentId, avoidAreaType);
8411 needUpdate = false;
8412 return needUpdate;
8413 }
8414 }
8415 if (needUpdate) {
8416 lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
8417 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
8418 }
8419
8420 return needUpdate;
8421 }
8422
UpdateAvoidSessionAvoidArea(WindowType type,bool & needUpdate)8423 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
8424 {
8425 bool ret = true;
8426 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
8427 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
8428 for (auto& persistentId : avoidAreaListenerSessionSet_) {
8429 auto sceneSession = GetSceneSession(persistentId);
8430 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8431 continue;
8432 }
8433 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8434 ret = UpdateSessionAvoidAreaIfNeed(
8435 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8436 needUpdate = needUpdate || ret;
8437 }
8438
8439 return;
8440 }
8441
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)8442 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
8443 {
8444 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
8445 !avoidArea.rightRect_.IsUninitializedRect()) {
8446 return false;
8447 }
8448 if (avoidArea.bottomRect_.IsUninitializedRect()) {
8449 return true;
8450 }
8451 if (isVisible &&
8452 (avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) == sessionBottom)) {
8453 return true;
8454 }
8455 return false;
8456 }
8457
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)8458 void SceneSessionManager::UpdateNormalSessionAvoidArea(
8459 const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
8460 {
8461 bool ret = true;
8462 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8463 TLOGI(WmsLogTag::WMS_IMMS, "id: %{public}u, isVisible: %{public}u, sessionState: %{public}u",
8464 persistentId, sceneSession->IsVisible(), sceneSession->GetSessionState());
8465 needUpdate = false;
8466 return;
8467 }
8468 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8469 TLOGD(WmsLogTag::WMS_IMMS,
8470 "id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
8471 needUpdate = false;
8472 return;
8473 }
8474 uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
8475 uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8476 for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
8477 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
8478 if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
8479 !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8480 sceneSession->GetSessionRect().height_)) {
8481 continue;
8482 }
8483 ret = UpdateSessionAvoidAreaIfNeed(
8484 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
8485 needUpdate = needUpdate || ret;
8486 }
8487
8488 return;
8489 }
8490
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)8491 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
8492 {
8493 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
8494 auto sceneSession = GetSceneSession(windowId);
8495 if (sceneSession == nullptr) {
8496 WLOGFW("window not exist: %{public}d", windowId);
8497 return;
8498 }
8499
8500 wptr<SceneSession> weakSceneSession(sceneSession);
8501 WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
8502 auto task = [weakSceneSession, startMoving]() -> WSError {
8503 auto scnSession = weakSceneSession.promote();
8504 if (scnSession == nullptr) {
8505 WLOGFW("session is null");
8506 return WSError::WS_ERROR_NULLPTR;
8507 }
8508 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
8509 return WSError::WS_OK;
8510 };
8511 return taskScheduler_->PostAsyncTask(task);
8512 }
8513
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)8514 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
8515 const std::string taskName, const int delayTime)
8516 {
8517 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
8518 }
8519
UpdateAvoidArea(int32_t persistentId)8520 void SceneSessionManager::UpdateAvoidArea(int32_t persistentId)
8521 {
8522 auto task = [this, persistentId] {
8523 bool needUpdate = false;
8524 auto sceneSession = GetSceneSession(persistentId);
8525 if (sceneSession == nullptr) {
8526 TLOGD(WmsLogTag::WMS_IMMS, "sceneSession is nullptr.");
8527 return;
8528 }
8529 WindowType type = sceneSession->GetWindowType();
8530 if (sceneSession->IsImmersiveType()) {
8531 UpdateAvoidSessionAvoidArea(type, needUpdate);
8532 } else {
8533 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
8534 }
8535 if (needUpdate) {
8536 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
8537 }
8538 return;
8539 };
8540 taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
8541 return;
8542 }
8543
UpdateAvoidAreaByType(int32_t persistentId,AvoidAreaType type)8544 void SceneSessionManager::UpdateAvoidAreaByType(int32_t persistentId, AvoidAreaType type)
8545 {
8546 auto task = [this, persistentId, type] {
8547 auto sceneSession = GetSceneSession(persistentId);
8548 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8549 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is nullptr or invisible", persistentId);
8550 return;
8551 }
8552 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
8553 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d has no listener, no need update", persistentId);
8554 return;
8555 }
8556 if (sceneSession->IsImmersiveType()) {
8557 TLOGND(WmsLogTag::WMS_IMMS, "window %{public}d is immersive type", persistentId);
8558 return;
8559 }
8560 auto avoidArea = sceneSession->GetAvoidAreaByType(type);
8561 if (type == AvoidAreaType::TYPE_NAVIGATION_INDICATOR && !CheckAvoidAreaForAINavigationBar(
8562 isAINavigationBarVisible_, avoidArea, sceneSession->GetSessionRect().height_)) {
8563 return;
8564 }
8565 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea, type);
8566 };
8567 taskScheduler_->PostAsyncTask(task, "UpdateAvoidAreaByType:PID:" + std::to_string(persistentId));
8568 }
8569
UpdateGestureBackEnabled(int32_t persistentId)8570 void SceneSessionManager::UpdateGestureBackEnabled(int32_t persistentId)
8571 {
8572 auto task = [this, persistentId] {
8573 auto sceneSession = GetSceneSession(persistentId);
8574 if (sceneSession == nullptr || !sceneSession->GetEnableGestureBackHadSet()) {
8575 TLOGNI(WmsLogTag::WMS_IMMS, "sceneSession is nullptr or not set Gesture Back enable.");
8576 return;
8577 }
8578 auto needEnableGestureBack = sceneSession->GetGestureBackEnabled();
8579 if (needEnableGestureBack) {
8580 gestureBackEnableWindowIdSet_.erase(persistentId);
8581 } else {
8582 gestureBackEnableWindowIdSet_.insert(persistentId);
8583 }
8584 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
8585 sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN ||
8586 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8587 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) ||
8588 enterRecent_.load() || !sceneSession->IsFocused()) {
8589 needEnableGestureBack = true;
8590 }
8591 if (gestureNavigationEnabledChangeFunc_ != nullptr) {
8592 gestureNavigationEnabledChangeFunc_(needEnableGestureBack,
8593 sceneSession->GetSessionInfo().bundleName_, GestureBackType::GESTURE_SIDE);
8594 } else {
8595 TLOGNE(WmsLogTag::WMS_IMMS, "callback func is null");
8596 }
8597 };
8598 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabled: PID: " + std::to_string(persistentId));
8599 }
8600
UpdateOccupiedAreaIfNeed(const int32_t & persistentId)8601 void SceneSessionManager::UpdateOccupiedAreaIfNeed(const int32_t& persistentId)
8602 {
8603 auto task = [this, persistentId]() {
8604 sptr<SceneSession> keyboardSession = nullptr;
8605 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8606 for (auto item = sceneSessionMap_.rbegin(); item != sceneSessionMap_.rend(); ++item) {
8607 auto sceneSession = item->second;
8608 if (sceneSession != nullptr &&
8609 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
8610 keyboardSession = sceneSession;
8611 break;
8612 }
8613 }
8614 if (keyboardSession == nullptr) {
8615 TLOGE(WmsLogTag::WMS_KEYBOARD, "keyboardSession is nullptr.");
8616 return;
8617 }
8618 if (keyboardSession->GetCallingSessionId() != static_cast<uint32_t>(persistentId)) {
8619 return;
8620 }
8621
8622 keyboardSession->OnCallingSessionUpdated();
8623 return;
8624 };
8625 taskScheduler_->PostAsyncTask(task, "UpdateOccupiedAreaIfNeed:PID:" + std::to_string(persistentId));
8626 return;
8627 }
8628
NotifyStatusBarShowStatus(int32_t persistentId,bool isVisible)8629 WSError SceneSessionManager::NotifyStatusBarShowStatus(int32_t persistentId, bool isVisible)
8630 {
8631 TLOGD(WmsLogTag::WMS_IMMS, "isVisible %{public}u, persistentId %{public}u",
8632 isVisible, persistentId);
8633 auto task = [this, persistentId, isVisible] {
8634 auto sceneSession = GetSceneSession(persistentId);
8635 if (sceneSession == nullptr) {
8636 TLOGE(WmsLogTag::WMS_IMMS, "scene session is nullptr");
8637 return;
8638 }
8639 sceneSession->SetIsStatusBarVisible(isVisible);
8640 };
8641 taskScheduler_->PostTask(task, "NotifyStatusBarShowStatus");
8642 return WSError::WS_OK;
8643 }
8644
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea,uint64_t displayId)8645 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea, uint64_t displayId)
8646 {
8647 WLOGFI("isVisible: %{public}u, "
8648 "area{%{public}d,%{public}d,%{public}d,%{public}d}, displayId: %{public}" PRIu64,
8649 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_, displayId);
8650 auto task = [this, isVisible, barArea, displayId]() {
8651 bool isNeedUpdate = true;
8652 {
8653 std::unique_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8654 isNeedUpdate = isAINavigationBarVisible_ != isVisible ||
8655 currAINavigationBarAreaMap_.count(displayId) == 0 ||
8656 currAINavigationBarAreaMap_[displayId] != barArea;
8657 if (isNeedUpdate) {
8658 isAINavigationBarVisible_ = isVisible;
8659 currAINavigationBarAreaMap_.clear();
8660 currAINavigationBarAreaMap_[displayId] = barArea;
8661 }
8662 if (isNeedUpdate && !isVisible && !barArea.IsEmpty()) {
8663 WLOGFD("NotifyAINavigationBar: barArea should be empty if invisible");
8664 currAINavigationBarAreaMap_[displayId] = WSRect();
8665 }
8666 }
8667 if (isNeedUpdate) {
8668 WLOGFI("NotifyAINavigationBar inner: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
8669 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
8670 for (auto persistentId : avoidAreaListenerSessionSet_) {
8671 NotifySessionAINavigationBarChange(persistentId);
8672 }
8673 }
8674 };
8675 taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
8676 return WSError::WS_OK;
8677 }
8678
NotifySessionAINavigationBarChange(int32_t persistentId)8679 void SceneSessionManager::NotifySessionAINavigationBarChange(int32_t persistentId)
8680 {
8681 auto sceneSession = GetSceneSession(persistentId);
8682 if (sceneSession == nullptr || !IsSessionVisibleForeground(sceneSession)) {
8683 return;
8684 }
8685 bool isLastFrameLayoutFinished = true;
8686 IsLastFrameLayoutFinished(isLastFrameLayoutFinished);
8687 TLOGI(WmsLogTag::WMS_IMMS, "window [%{public}d] is layout finished: %{public}d",
8688 persistentId, isLastFrameLayoutFinished);
8689 if (isLastFrameLayoutFinished) {
8690 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8691 if (!CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
8692 sceneSession->GetSessionRect().height_)) {
8693 return;
8694 }
8695 TLOGI(WmsLogTag::WMS_IMMS, "window [%{public}d] immediate update aibar area %{public}s",
8696 persistentId, avoidArea.ToString().c_str());
8697 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
8698 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
8699 } else {
8700 sceneSession->MarkAvoidAreaAsDirty();
8701 }
8702 }
8703
GetAINavigationBarArea(uint64_t displayId)8704 WSRect SceneSessionManager::GetAINavigationBarArea(uint64_t displayId)
8705 {
8706 std::shared_lock<std::shared_mutex> lock(currAINavigationBarAreaMapMutex_);
8707 if (currAINavigationBarAreaMap_.count(displayId) == 0) {
8708 return {};
8709 }
8710 return currAINavigationBarAreaMap_[displayId];
8711 }
8712
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)8713 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
8714 {
8715 const auto callingPid = IPCSkeleton::GetCallingRealPid();
8716 auto task = [this, persistentId, haveListener, callingPid]() {
8717 TLOGI(WmsLogTag::WMS_EVENT, "persistentId:%{public}d haveListener:%{public}d",
8718 persistentId, haveListener);
8719 auto sceneSession = GetSceneSession(persistentId);
8720 if (sceneSession == nullptr) {
8721 TLOGE(WmsLogTag::WMS_EVENT, "sceneSession is nullptr.");
8722 return WSError::WS_DO_NOTHING;
8723 }
8724 if (callingPid != sceneSession->GetCallingPid()) {
8725 TLOGE(WmsLogTag::WMS_EVENT, "Permission denied");
8726 return WSError::WS_ERROR_INVALID_PERMISSION;
8727 }
8728 if (haveListener) {
8729 touchOutsideListenerSessionSet_.insert(persistentId);
8730 } else {
8731 touchOutsideListenerSessionSet_.erase(persistentId);
8732 }
8733 return WSError::WS_OK;
8734 };
8735 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
8736 }
8737
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)8738 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
8739 {
8740 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
8741 auto task = [this, persistentId, haveListener, callingPid]() -> WSError {
8742 WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
8743 persistentId, haveListener);
8744 auto sceneSession = GetSceneSession(persistentId);
8745 if (sceneSession == nullptr) {
8746 WLOGFD("sceneSession is nullptr.");
8747 return WSError::WS_DO_NOTHING;
8748 }
8749 if (callingPid != sceneSession->GetCallingPid()) {
8750 TLOGE(WmsLogTag::WMS_LIFE, "Permission denied, neither register nor unreigster allowed by other process");
8751 return WSError::WS_ERROR_INVALID_PERMISSION;
8752 }
8753 if (haveListener) {
8754 windowVisibilityListenerSessionSet_.insert(persistentId);
8755 sceneSession->NotifyWindowVisibility();
8756 } else {
8757 windowVisibilityListenerSessionSet_.erase(persistentId);
8758 }
8759 return WSError::WS_OK;
8760 };
8761 return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
8762 }
8763
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)8764 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
8765 {
8766 processVirtualPixelRatioChangeFunc_ = func;
8767 WLOGFI("SetVirtualPixelRatioChangeListener");
8768 }
8769
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8770 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8771 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8772 {
8773 if (displayInfo == nullptr) {
8774 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
8775 return;
8776 }
8777 auto task = [this, displayInfo]() {
8778 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8779 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
8780 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
8781 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
8782 displayInfo->GetWidth(), displayInfo->GetHeight()
8783 };
8784 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
8785 }
8786 for (const auto &item : sceneSessionMap_) {
8787 auto scnSession = item.second;
8788 if (scnSession == nullptr) {
8789 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
8790 continue;
8791 }
8792 SessionInfo sessionInfo = scnSession->GetSessionInfo();
8793 if (sessionInfo.isSystem_) {
8794 continue;
8795 }
8796 if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
8797 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
8798 scnSession->UpdateDensity();
8799 WLOGFD("UpdateDensity name=%{public}s, persistentId=%{public}d, winType=%{public}d, "
8800 "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
8801 scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8802 }
8803 }
8804 UpdateDisplayRegion(displayInfo);
8805 return WSError::WS_OK;
8806 };
8807 taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
8808 }
8809
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8810 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8811 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8812 {
8813 if (displayInfo == nullptr) {
8814 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
8815 return;
8816 }
8817 auto task = [this, displayInfo]() {
8818 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8819 for (const auto &item : sceneSessionMap_) {
8820 auto scnSession = item.second;
8821 if (scnSession == nullptr) {
8822 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
8823 continue;
8824 }
8825 if (scnSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
8826 scnSession->GetSessionState() != SessionState::STATE_ACTIVE) {
8827 continue;
8828 }
8829 if (NearEqual(scnSession->GetBounds().width_, static_cast<float>(displayInfo->GetWidth())) &&
8830 NearEqual(scnSession->GetBounds().height_, static_cast<float>(displayInfo->GetHeight())) &&
8831 scnSession->GetRotation() != displayInfo->GetRotation()) {
8832 scnSession->UpdateRotationAvoidArea();
8833 TLOGD(WmsLogTag::DMS, "UpdateRotationAvoidArea name=%{public}s, persistentId=%{public}d, "
8834 "winType=%{public}d, state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(),
8835 item.first, scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
8836 }
8837 scnSession->SetRotation(displayInfo->GetRotation());
8838 scnSession->UpdateOrientation();
8839 }
8840 UpdateDisplayRegion(displayInfo);
8841 return WSError::WS_OK;
8842 };
8843 taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
8844 }
8845
ProcessDisplayScale(sptr<DisplayInfo> & displayInfo)8846 void SceneSessionManager::ProcessDisplayScale(sptr<DisplayInfo>& displayInfo)
8847 {
8848 if (displayInfo == nullptr) {
8849 TLOGE(WmsLogTag::DMS, "displayInfo is nullptr");
8850 return;
8851 }
8852
8853 auto task = [displayInfo]() -> WSError {
8854 ScreenSessionManagerClient::GetInstance().UpdateDisplayScale(displayInfo->GetScreenId(),
8855 displayInfo->GetScaleX(),
8856 displayInfo->GetScaleY(),
8857 displayInfo->GetPivotX(),
8858 displayInfo->GetPivotY(),
8859 displayInfo->GetTranslateX(),
8860 displayInfo->GetTranslateY());
8861 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
8862 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(true);
8863 return WSError::WS_OK;
8864 };
8865 return taskScheduler_->PostAsyncTask(task);
8866 }
8867
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)8868 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
8869 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
8870 {
8871 WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
8872 switch (type) {
8873 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
8874 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
8875 displayInfo, displayInfoMap, type);
8876 break;
8877 }
8878 case DisplayStateChangeType::UPDATE_ROTATION: {
8879 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
8880 displayInfo, displayInfoMap, type);
8881 break;
8882 }
8883 case DisplayStateChangeType::UPDATE_SCALE: {
8884 SceneSessionManager::GetInstance().ProcessDisplayScale(displayInfo);
8885 break;
8886 }
8887 default:
8888 return;
8889 }
8890 }
8891
OnScreenshot(DisplayId displayId)8892 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
8893 {
8894 SceneSessionManager::GetInstance().OnScreenshot(displayId);
8895 }
8896
OnScreenshot(DisplayId displayId)8897 void SceneSessionManager::OnScreenshot(DisplayId displayId)
8898 {
8899 auto task = [this, displayId]() {
8900 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8901 for (const auto& iter : sceneSessionMap_) {
8902 auto sceneSession = iter.second;
8903 if (sceneSession == nullptr) {
8904 continue;
8905 }
8906 auto state = sceneSession->GetSessionState();
8907 if (state == SessionState::STATE_FOREGROUND || state == SessionState::STATE_ACTIVE) {
8908 sceneSession->NotifyScreenshot();
8909 }
8910 }
8911 };
8912 taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
8913 }
8914
ClearSession(int32_t persistentId)8915 WSError SceneSessionManager::ClearSession(int32_t persistentId)
8916 {
8917 WLOGFI("id: %{public}d", persistentId);
8918 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8919 WLOGFE("The caller is not system-app, can not use system-api");
8920 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8921 }
8922 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8923 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8924 return WSError::WS_ERROR_INVALID_PERMISSION;
8925 }
8926 auto task = [this, persistentId]() {
8927 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
8928 return ClearSession(sceneSession);
8929 };
8930 taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
8931 return WSError::WS_OK;
8932 }
8933
ClearSession(sptr<SceneSession> sceneSession)8934 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
8935 {
8936 WLOGFD("Enter");
8937 if (sceneSession == nullptr) {
8938 WLOGFE("session is nullptr");
8939 return WSError::WS_ERROR_INVALID_SESSION;
8940 }
8941 if (!IsSessionClearable(sceneSession)) {
8942 WLOGFI("session cannot be clear, Id %{public}d.", sceneSession->GetPersistentId());
8943 return WSError::WS_ERROR_INVALID_SESSION;
8944 }
8945 const WSError errCode = sceneSession->Clear();
8946 return errCode;
8947 }
8948
ClearAllSessions()8949 WSError SceneSessionManager::ClearAllSessions()
8950 {
8951 WLOGFD("Enter");
8952 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8953 WLOGFE("The caller is not system-app, can not use system-api");
8954 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8955 }
8956 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8957 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8958 return WSError::WS_ERROR_INVALID_PERMISSION;
8959 }
8960 auto task = [this]() {
8961 std::vector<sptr<SceneSession>> sessionVector;
8962 GetAllClearableSessions(sessionVector);
8963 for (uint32_t i = 0; i < sessionVector.size(); i++) {
8964 ClearSession(sessionVector[i]);
8965 }
8966 return WSError::WS_OK;
8967 };
8968 taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
8969 return WSError::WS_OK;
8970 }
8971
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)8972 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
8973 {
8974 WLOGFD("Enter");
8975 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
8976 for (const auto &item : sceneSessionMap_) {
8977 auto scnSession = item.second;
8978 if (IsSessionClearable(scnSession)) {
8979 sessionVector.push_back(scnSession);
8980 }
8981 }
8982 }
8983
LockSession(int32_t sessionId)8984 WSError SceneSessionManager::LockSession(int32_t sessionId)
8985 {
8986 WLOGFI("id: %{public}d", sessionId);
8987 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
8988 WLOGFE("The caller is not system-app, can not use system-api");
8989 return WSError::WS_ERROR_NOT_SYSTEM_APP;
8990 }
8991 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
8992 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
8993 return WSError::WS_ERROR_INVALID_PERMISSION;
8994 }
8995 auto task = [this, sessionId]() {
8996 auto sceneSession = GetSceneSession(sessionId);
8997 if (sceneSession == nullptr) {
8998 WLOGFE("LockSession cannot find session, id: %{public}d", sessionId);
8999 return WSError::WS_ERROR_INVALID_PARAM;
9000 }
9001 sceneSession->SetSessionInfoLockedState(true);
9002 return WSError::WS_OK;
9003 };
9004 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
9005 }
9006
UnlockSession(int32_t sessionId)9007 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
9008 {
9009 WLOGFI("id: %{public}d", sessionId);
9010 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9011 WLOGFE("The caller is not system-app, can not use system-api");
9012 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9013 }
9014 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9015 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9016 return WSError::WS_ERROR_INVALID_PERMISSION;
9017 }
9018 auto task = [this, sessionId]() {
9019 auto sceneSession = GetSceneSession(sessionId);
9020 if (sceneSession == nullptr) {
9021 WLOGFE("UnlockSession cannot find session, id: %{public}d", sessionId);
9022 return WSError::WS_ERROR_INVALID_PARAM;
9023 }
9024 sceneSession->SetSessionInfoLockedState(false);
9025 return WSError::WS_OK;
9026 };
9027 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
9028 }
9029
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)9030 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
9031 {
9032 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9033 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9034 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9035 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9036 }
9037 if (!SessionPermission::VerifySessionPermission()) {
9038 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9039 return WSError::WS_ERROR_INVALID_PERMISSION;
9040 }
9041
9042 return WSError::WS_OK;
9043 }
9044
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)9045 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
9046 std::vector<int32_t>& result)
9047 {
9048 TLOGI(WmsLogTag::WMS_LIFE, "Enter");
9049 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
9050 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system-app, can not use system-api");
9051 return WSError::WS_ERROR_NOT_SYSTEM_APP;
9052 }
9053 if (!SessionPermission::VerifySessionPermission()) {
9054 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
9055 return WSError::WS_ERROR_INVALID_PERMISSION;
9056 }
9057
9058 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
9059 return WSError::WS_OK;
9060 }
9061
IsSessionClearable(sptr<SceneSession> scnSession)9062 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
9063 {
9064 if (scnSession == nullptr) {
9065 WLOGFI("scnSession is nullptr");
9066 return false;
9067 }
9068 SessionInfo sessionInfo = scnSession->GetSessionInfo();
9069 if (sessionInfo.abilityInfo == nullptr) {
9070 WLOGFI("scnSession abilityInfo is nullptr");
9071 return false;
9072 }
9073 if (sessionInfo.abilityInfo->excludeFromMissions && !scnSession->IsAnco()) {
9074 WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
9075 return false;
9076 }
9077 if (sessionInfo.abilityInfo->unclearableMission) {
9078 WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
9079 return false;
9080 }
9081 if (sessionInfo.isSystem_) {
9082 WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
9083 return false;
9084 }
9085 if (sessionInfo.lockedState) {
9086 WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
9087 return false;
9088 }
9089
9090 return true;
9091 }
9092
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)9093 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
9094 const sptr<AAFwk::IAbilityManagerCollaborator>& impl)
9095 {
9096 WLOGFI("type: %{public}d", type);
9097 auto isSaCall = SessionPermission::IsSACalling();
9098 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9099 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9100 return WSError::WS_ERROR_INVALID_PERMISSION;
9101 }
9102 if (!CheckCollaboratorType(type)) {
9103 WLOGFW("collaborator register failed, invalid type.");
9104 return WSError::WS_ERROR_INVALID_TYPE;
9105 }
9106 {
9107 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9108 collaboratorMap_[type] = impl;
9109 }
9110 auto task = [this] {
9111 if (abilityManagerCollaboratorRegisteredFunc_) {
9112 abilityManagerCollaboratorRegisteredFunc_();
9113 }
9114 };
9115 taskScheduler_->PostTask(task, __func__);
9116 return WSError::WS_OK;
9117 }
9118
UnregisterIAbilityManagerCollaborator(int32_t type)9119 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
9120 {
9121 WLOGFI("type: %{public}d", type);
9122 auto isSaCall = SessionPermission::IsSACalling();
9123 if (!isSaCall || !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
9124 TLOGE(WmsLogTag::DEFAULT, "The caller has not permission granted or not SACalling");
9125 return WSError::WS_ERROR_INVALID_PERMISSION;
9126 }
9127 if (!CheckCollaboratorType(type)) {
9128 WLOGFE("collaborator unregister failed, invalid type.");
9129 return WSError::WS_ERROR_INVALID_TYPE;
9130 }
9131 {
9132 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
9133 collaboratorMap_.erase(type);
9134 }
9135 return WSError::WS_OK;
9136 }
9137
CheckCollaboratorType(int32_t type)9138 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
9139 {
9140 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
9141 WLOGFD("type is invalid");
9142 return false;
9143 }
9144 return true;
9145 }
9146
CheckIfReuseSession(SessionInfo & sessionInfo)9147 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
9148 {
9149 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
9150 sessionInfo.moduleName_);
9151 if (abilityInfo == nullptr) {
9152 WLOGFE("abilityInfo is nullptr!");
9153 return BrokerStates::BROKER_UNKOWN;
9154 }
9155 sessionInfo.abilityInfo = abilityInfo;
9156 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
9157 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
9158 collaboratorType = CollaboratorType::RESERVE_TYPE;
9159 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
9160 collaboratorType = CollaboratorType::OTHERS_TYPE;
9161 }
9162 if (!CheckCollaboratorType(collaboratorType)) {
9163 WLOGFW("checked not collaborator!");
9164 return BrokerStates::BROKER_UNKOWN;
9165 }
9166 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
9167 sessionInfo.collaboratorType_ = collaboratorType;
9168 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9169 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
9170 WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
9171 sessionInfo.reuse = true;
9172 } else {
9173 sessionInfo.reuse = false;
9174 }
9175 WLOGFI("end: affinity %{public}s type %{public}d reuse %{public}d",
9176 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
9177 return resultValue;
9178 }
9179
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)9180 BrokerStates SceneSessionManager::NotifyStartAbility(
9181 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
9182 {
9183 WLOGFI("type %{public}d id %{public}d", collaboratorType, persistentId);
9184 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9185 if (collaborator == nullptr) {
9186 return BrokerStates::BROKER_UNKOWN;
9187 }
9188 if (sessionInfo.want == nullptr) {
9189 WLOGFI("sessionInfo.want is nullptr, init");
9190 sessionInfo.want = std::make_shared<AAFwk::Want>();
9191 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
9192 sessionInfo.moduleName_);
9193 }
9194 auto accessTokenIDEx = sessionInfo.callingTokenId_;
9195 if (collaborator != nullptr) {
9196 containerStartAbilityTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
9197 std::chrono::system_clock::now().time_since_epoch()).count();
9198
9199 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9200 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
9201 WLOGFI("want affinity exit %{public}s.", affinity.c_str());
9202 return BrokerStates::BROKER_UNKOWN;
9203 }
9204 sessionInfo.want->SetParam("oh_persistentId", persistentId);
9205 int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
9206 currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
9207 WLOGFI("collaborator ret: %{public}d", ret);
9208 if (ret == 0) {
9209 return BrokerStates::BROKER_STARTED;
9210 } else {
9211 return BrokerStates::BROKER_NOT_START;
9212 }
9213 }
9214 return BrokerStates::BROKER_UNKOWN;
9215 }
9216
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)9217 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
9218 {
9219 if (sceneSession == nullptr) {
9220 WLOGFE("sceneSession is nullptr");
9221 return;
9222 }
9223 if (sessionInfo.want == nullptr) {
9224 WLOGFI("sessionInfo.want is nullptr");
9225 return;
9226 }
9227 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9228 if (collaborator == nullptr) {
9229 return;
9230 }
9231 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9232 if (abilitySessionInfo == nullptr) {
9233 WLOGFE("abilitySessionInfo is nullptr");
9234 return;
9235 }
9236 abilitySessionInfo->want = *(sessionInfo.want);
9237 if (collaborator != nullptr) {
9238 int32_t missionId = abilitySessionInfo->persistentId;
9239 std::string bundleName = sessionInfo.bundleName_;
9240 int64_t timestamp = containerStartAbilityTime_;
9241 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
9242 WLOGFI("call NotifyMissionCreated, persistentId: %{public}d, bundleName: %{public}s",
9243 missionId, bundleName.c_str());
9244 collaborator->NotifyMissionCreated(abilitySessionInfo);
9245 }
9246 }
9247
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)9248 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
9249 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
9250 {
9251 WLOGFD("type: %{public}d", collaboratorType);
9252 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9253 if (collaborator != nullptr) {
9254 WLOGFI("called NotifyLoadAbility");
9255 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
9256 }
9257 }
9258
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)9259 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
9260 {
9261 WLOGFD("Enter");
9262 if (sceneSession == nullptr) {
9263 WLOGFE("sceneSession is nullptr");
9264 return;
9265 }
9266 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(sceneSession->GetCollaboratorType());
9267 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
9268 if (collaborator != nullptr) {
9269 WLOGFI("called UpdateMissionInfo");
9270 collaborator->UpdateMissionInfo(abilitySessionInfo);
9271 }
9272 }
9273
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)9274 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
9275 {
9276 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9277 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9278 if (collaborator != nullptr) {
9279 WLOGFI("called NotifyMoveMissionToForeground %{public}d", persistentId);
9280 collaborator->NotifyMoveMissionToForeground(persistentId);
9281 }
9282 }
9283
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)9284 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
9285 {
9286 WLOGFD("id: %{public}d, type: %{public}d", persistentId, collaboratorType);
9287 sptr<AAFwk::IAbilityManagerCollaborator> collaborator = GetCollaboratorByType(collaboratorType);
9288 if (collaborator != nullptr) {
9289 WLOGFI("called NotifyClearMission %{public}d", persistentId);
9290 collaborator->NotifyClearMission(persistentId);
9291 }
9292 }
9293
PreHandleCollaboratorStartAbility(sptr<SceneSession> & sceneSession,int32_t persistentId)9294 bool SceneSessionManager::PreHandleCollaboratorStartAbility(sptr<SceneSession>& sceneSession, int32_t persistentId)
9295 {
9296 if (sceneSession == nullptr) {
9297 TLOGE(WmsLogTag::WMS_LIFE, "sceneSession is null");
9298 return false;
9299 }
9300 std::string sessionAffinity;
9301 TLOGI(WmsLogTag::WMS_LIFE, "call");
9302 if (sceneSession->GetSessionInfo().want != nullptr) {
9303 sessionAffinity = sceneSession->GetSessionInfo().want
9304 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
9305 }
9306 if (sessionAffinity.empty()) {
9307 TLOGI(WmsLogTag::WMS_LIFE, "Session affinity is empty");
9308 BrokerStates notifyReturn = NotifyStartAbility(
9309 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
9310 if (notifyReturn == BrokerStates::BROKER_NOT_START) {
9311 TLOGE(WmsLogTag::WMS_LIFE, "notifyReturn not BROKER_STARTED!");
9312 return false;
9313 }
9314 }
9315 if (sceneSession->GetSessionInfo().want != nullptr) {
9316 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
9317 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
9318 TLOGI(WmsLogTag::WMS_LIFE, "ANCO_SESSION_ID: %{public}d, want affinity: %{public}s.",
9319 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0),
9320 sceneSession->GetSessionInfo().sessionAffinity.c_str());
9321 } else {
9322 TLOGI(WmsLogTag::WMS_LIFE, "sceneSession->GetSessionInfo().want is nullptr");
9323 }
9324 return true;
9325 }
9326
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)9327 bool SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
9328 {
9329 if (!PreHandleCollaboratorStartAbility(sceneSession, persistentId)) {
9330 return false;
9331 }
9332 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
9333 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
9334 return true;
9335 }
9336
AddWindowDragHotArea(uint32_t type,WSRect & area)9337 void SceneSessionManager::AddWindowDragHotArea(uint32_t type, WSRect& area)
9338 {
9339 WLOGFI("type: %{public}d, posX: %{public}d, posY: %{public}d, width: %{public}d, "
9340 "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
9341 SceneSession::AddOrUpdateWindowDragHotArea(type, area);
9342 }
9343
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)9344 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
9345 {
9346 auto task = [this, persistentId, isMaximize]() -> WSError {
9347 WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
9348 auto sceneSession = GetSceneSession(persistentId);
9349 if (sceneSession == nullptr) {
9350 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9351 return WSError::WS_ERROR_INVALID_WINDOW;
9352 }
9353 sceneSession->UpdateMaximizeMode(isMaximize);
9354 return WSError::WS_OK;
9355 };
9356 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
9357 return WSError::WS_OK;
9358 }
9359
GetIsLayoutFullScreen(bool & isLayoutFullScreen)9360 WSError SceneSessionManager::GetIsLayoutFullScreen(bool& isLayoutFullScreen)
9361 {
9362 auto task = [this, &isLayoutFullScreen]() {
9363 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9364 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
9365 auto sceneSession = item->second;
9366 if (sceneSession == nullptr) {
9367 WLOGFE("Session is nullptr");
9368 continue;
9369 }
9370 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9371 continue;
9372 }
9373 auto state = sceneSession->GetSessionState();
9374 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9375 continue;
9376 }
9377 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9378 continue;
9379 }
9380 auto property = sceneSession->GetSessionProperty();
9381 if (property == nullptr) {
9382 WLOGFE("Property is nullptr");
9383 continue;
9384 }
9385 isLayoutFullScreen = property->IsLayoutFullScreen();
9386 auto persistentId = sceneSession->GetPersistentId();
9387 if (isLayoutFullScreen) {
9388 WLOGFD("Current window is immersive, persistentId:%{public}d", persistentId);
9389 return WSError::WS_OK;
9390 } else {
9391 WLOGFD("Current window is not immersive, persistentId:%{public}d", persistentId);
9392 }
9393 }
9394 WLOGFD("No immersive window");
9395 return WSError::WS_OK;
9396 };
9397
9398 taskScheduler_->PostSyncTask(task, "GetIsLayoutFullScreen");
9399 return WSError::WS_OK;
9400 }
9401
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)9402 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
9403 {
9404 auto scnSession = GetSceneSession(persistentId);
9405 if (!scnSession) {
9406 WLOGFE("session is nullptr");
9407 return WSError::WS_ERROR_INVALID_WINDOW;
9408 }
9409 auto fromScreenId = scnSession->GetSessionInfo().screenId_;
9410 scnSession->SetScreenId(screenId);
9411 auto sessionProperty = scnSession->GetSessionProperty();
9412 if (!sessionProperty) {
9413 WLOGFE("Property is null, synchronous screenId failed");
9414 return WSError::WS_ERROR_NULLPTR;
9415 }
9416 sessionProperty->SetDisplayId(screenId);
9417 WLOGFD("Session move display %{public}" PRIu64 " from %{public}" PRIu64, screenId, fromScreenId);
9418 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
9419 scnSession->NotifyDisplayMove(fromScreenId, screenId);
9420 scnSession->UpdateDensity();
9421 return WSError::WS_OK;
9422 }
9423
NotifyStackEmpty(int32_t persistentId)9424 WSError SceneSessionManager::NotifyStackEmpty(int32_t persistentId)
9425 {
9426 TLOGI(WmsLogTag::WMS_LIFE, "NotifyStackEmpty, persistentId %{public}d", persistentId);
9427 auto task = [this, persistentId]() {
9428 auto scnSession = GetSceneSession(persistentId);
9429 if (!scnSession) {
9430 TLOGE(WmsLogTag::WMS_LIFE, "session is nullptr");
9431 return WSError::WS_ERROR_INVALID_WINDOW;
9432 }
9433 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::STACK_EMPTY);
9434 return WSError::WS_OK;
9435 };
9436 taskScheduler_->PostAsyncTask(task, "NotifyStackEmpty:PID:" + std::to_string(persistentId));
9437 return WSError::WS_OK;
9438 }
9439
OnImmersiveStateChange(bool & immersive)9440 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
9441 {
9442 immersive = SceneSessionManager::GetInstance().GetImmersiveState();
9443 }
9444
GetImmersiveState()9445 bool SceneSessionManager::GetImmersiveState()
9446 {
9447 return taskScheduler_->PostSyncTask([this, where = __func__] {
9448 bool isPcOrPadFreeMultiWindowMode = false;
9449 IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
9450 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9451 for (const auto& [_, sceneSession] : sceneSessionMap_) {
9452 if (sceneSession == nullptr) {
9453 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is nullptr", where);
9454 continue;
9455 }
9456 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9457 continue;
9458 }
9459 auto state = sceneSession->GetSessionState();
9460 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
9461 continue;
9462 }
9463 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
9464 continue;
9465 }
9466 if (isPcOrPadFreeMultiWindowMode) {
9467 if (sceneSession->IsLayoutFullScreen()) {
9468 return true;
9469 }
9470 continue;
9471 }
9472 auto sysBarProperty = sceneSession->GetSessionProperty()->GetSystemBarProperty();
9473 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
9474 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s window is immersive. id: %{public}d", where,
9475 sceneSession->GetPersistentId());
9476 return true;
9477 } else {
9478 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s statusBar is enabled. id: %{public}d", where,
9479 sceneSession->GetPersistentId());
9480 break;
9481 }
9482 }
9483 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s not immersive", where);
9484 return false;
9485 }, __func__);
9486 }
9487
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)9488 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
9489 bool withAnimation)
9490 {
9491 session->NotifySessionForeground(reason, withAnimation);
9492 }
9493
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)9494 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
9495 bool withAnimation, bool isFromInnerkits)
9496 {
9497 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
9498 }
9499
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)9500 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
9501 {
9502 auto sceneSession = GetSceneSession(persistentId);
9503 if (sceneSession == nullptr) {
9504 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
9505 return WSError::WS_ERROR_INVALID_WINDOW;
9506 }
9507 return sceneSession->UpdateTitleInTargetPos(isShow, height);
9508 }
9509
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9510 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9511 {
9512 WLOGFI("AppAnrListener OnAppDebugStarted");
9513 if (debugInfos.empty()) {
9514 WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
9515 return;
9516 }
9517 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
9518 }
9519
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)9520 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo>& debugInfos)
9521 {
9522 WLOGFI("AppAnrListener OnAppDebugStoped");
9523 if (debugInfos.empty()) {
9524 WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
9525 return;
9526 }
9527 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
9528 }
9529
FlushUIParams(ScreenId screenId,std::unordered_map<int32_t,SessionUIParam> && uiParams)9530 void SceneSessionManager::FlushUIParams(ScreenId screenId, std::unordered_map<int32_t, SessionUIParam>&& uiParams)
9531 {
9532 if (!Session::IsScbCoreEnabled()) {
9533 return;
9534 }
9535 if (onFlushUIParamsFunc_ != nullptr) {
9536 onFlushUIParamsFunc_();
9537 }
9538 auto task = [this, screenId, uiParams = std::move(uiParams)]() {
9539 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushUIParams");
9540 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams");
9541 {
9542 std::unique_lock<std::mutex> lock(nextFlushCompletedMutex_);
9543 nextFlushCompletedCV_.notify_all();
9544 }
9545 std::vector<uint32_t> startingAppZOrderList;
9546 processingFlushUIParams_.store(true);
9547 {
9548 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9549 for (const auto& item : sceneSessionMap_) {
9550 auto sceneSession = item.second;
9551 if (sceneSession == nullptr) {
9552 continue;
9553 }
9554 if (sceneSession->GetSessionInfo().screenId_ != SCREEN_ID_INVALID &&
9555 sceneSession->GetSessionInfo().screenId_ != screenId) {
9556 continue;
9557 }
9558 auto iter = uiParams.find(sceneSession->GetPersistentId());
9559 if (iter != uiParams.end()) {
9560 if (sceneSession->GetSessionInfo().screenId_ == SCREEN_ID_INVALID) {
9561 sceneSession->SetScreenIdOnServer(screenId);
9562 }
9563 if ((systemConfig_.uiType_ == UI_TYPE_PHONE ||
9564 (systemConfig_.uiType_ == UI_TYPE_PAD && !systemConfig_.IsFreeMultiWindowMode())) &&
9565 sceneSession->GetStartingBeforeVisible() && sceneSession->IsAppSession()) {
9566 startingAppZOrderList.push_back(iter->second.zOrder_);
9567 sceneSession->SetStartingBeforeVisible(false);
9568 }
9569 sessionMapDirty_ |= sceneSession->UpdateUIParam(iter->second);
9570 } else {
9571 sessionMapDirty_ |= sceneSession->UpdateUIParam();
9572 }
9573 }
9574 }
9575 processingFlushUIParams_.store(false);
9576
9577 // post process if dirty
9578 if ((sessionMapDirty_ & (~static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA))) !=
9579 static_cast<uint32_t>(SessionUIDirtyFlag::NONE)) {
9580 TLOGD(WmsLogTag::WMS_PIPELINE, "FlushUIParams found dirty: %{public}d", sessionMapDirty_);
9581 for (const auto& item : uiParams) {
9582 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d, zOrder: %{public}d, rect: %{public}s, transX:%{public}f"
9583 " transY:%{public}f, needSync:%{public}d, intreactive:%{public}d", item.first, item.second.zOrder_,
9584 item.second.rect_.ToString().c_str(), item.second.transX_, item.second.transY_,
9585 item.second.needSync_, item.second.interactive_);
9586 }
9587 ProcessUpdateLastFocusedAppId(startingAppZOrderList);
9588 ProcessFocusZOrderChange(sessionMapDirty_);
9589 PostProcessFocus();
9590 PostProcessProperty(sessionMapDirty_);
9591 NotifyAllAccessibilityInfo();
9592 AnomalyDetection::SceneZOrderCheckProcess();
9593 } else if (sessionMapDirty_ == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9594 PostProcessProperty(sessionMapDirty_);
9595 }
9596 FlushWindowInfoToMMI();
9597 sessionMapDirty_ = 0;
9598 {
9599 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9600 for (const auto& item : sceneSessionMap_) {
9601 auto sceneSession = item.second;
9602 if (sceneSession == nullptr) {
9603 continue;
9604 }
9605 sceneSession->ResetSizeChangeReasonIfDirty();
9606 sceneSession->ResetDirtyFlags();
9607 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
9608 sceneSession->SetUIStateDirty(false);
9609 }
9610 }
9611 }
9612 };
9613 taskScheduler_->PostAsyncTask(task, "FlushUIParams");
9614 }
9615
ProcessUpdateLastFocusedAppId(const std::vector<uint32_t> & zOrderList)9616 void SceneSessionManager::ProcessUpdateLastFocusedAppId(const std::vector<uint32_t>& zOrderList)
9617 {
9618 TLOGD(WmsLogTag::WMS_FOCUS, "last focused app: %{public}d, list size %{public}zu", lastFocusedAppSessionId_,
9619 zOrderList.size());
9620 if (lastFocusedAppSessionId_ == INVALID_SESSION_ID || zOrderList.empty()) {
9621 return;
9622 }
9623 auto lastFocusedAppSession = GetSceneSession(lastFocusedAppSessionId_);
9624 if (lastFocusedAppSession == nullptr) {
9625 return;
9626 }
9627 uint32_t lastFocusedAppZOrder = lastFocusedAppSession->GetZOrder();
9628 auto it = std::find_if(zOrderList.begin(), zOrderList.end(), [lastFocusedAppZOrder](uint32_t zOrder) {
9629 return zOrder > lastFocusedAppZOrder;
9630 });
9631 if (it != zOrderList.end()) {
9632 TLOGD(WmsLogTag::WMS_FOCUS, "clear with high zOrder app visible");
9633 lastFocusedAppSessionId_ = INVALID_SESSION_ID;
9634 }
9635 }
9636
ProcessFocusZOrderChange(uint32_t dirty)9637 void SceneSessionManager::ProcessFocusZOrderChange(uint32_t dirty)
9638 {
9639 if (!(dirty & static_cast<uint32_t>(SessionUIDirtyFlag::Z_ORDER))) {
9640 return;
9641 }
9642 if (systemConfig_.uiType_ != UI_TYPE_PHONE && systemConfig_.uiType_ != UI_TYPE_PAD) {
9643 return;
9644 }
9645 TLOGD(WmsLogTag::WMS_FOCUS, "has zOrder dirty");
9646 auto focusedSession = GetSceneSession(focusedSessionId_);
9647 // only when it's from a high zOrder to a low zOrder
9648 if (focusedSession == nullptr || focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_VOICE_INTERACTION ||
9649 focusedSession->GetLastZOrder() <= focusedSession->GetZOrder()) {
9650 return;
9651 }
9652 auto voiceInteractionSession = GetSceneSessionByType(WindowType::WINDOW_TYPE_VOICE_INTERACTION);
9653 if (voiceInteractionSession == nullptr) {
9654 return;
9655 }
9656 TLOGD(WmsLogTag::WMS_FOCUS, "interactionSession: id %{public}d zOrder %{public}d, focusedSession: lastZOrder "
9657 "%{public}d zOrder %{public}d", voiceInteractionSession->GetPersistentId(),
9658 voiceInteractionSession->GetZOrder(), focusedSession->GetLastZOrder(), focusedSession->GetZOrder());
9659 if (focusedSession->GetLastZOrder() < voiceInteractionSession->GetZOrder() ||
9660 focusedSession->GetZOrder() > voiceInteractionSession->GetZOrder()) {
9661 return;
9662 }
9663 RequestSessionFocus(voiceInteractionSession->GetPersistentId(), true, FocusChangeReason::VOICE_INTERACTION);
9664 }
9665
PostProcessFocus()9666 void SceneSessionManager::PostProcessFocus()
9667 {
9668 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessFocus");
9669 // priority process focus requests from top to bottom
9670 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9671 {
9672 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9673 for (auto& iter : sceneSessionMap_) {
9674 auto session = iter.second;
9675 if (session == nullptr || !session->GetPostProcessFocusState().enabled_) {
9676 continue;
9677 }
9678 processingSessions.push_back(iter);
9679 }
9680 }
9681 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
9682 bool focusCmp = lhs.second->GetPostProcessFocusState().isFocused_ &&
9683 !rhs.second->GetPostProcessFocusState().isFocused_;
9684 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
9685 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
9686 return focusCmp || lhsZOrder > rhsZOrder;
9687 };
9688 std::sort(processingSessions.begin(), processingSessions.end(), cmp);
9689
9690 // only change focus one time
9691 bool focusChanged = false;
9692 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9693 auto session = iter->second;
9694 if (session == nullptr) {
9695 WLOGFE("session is nullptr");
9696 continue;
9697 }
9698 TLOGD(WmsLogTag::WMS_PIPELINE,
9699 "id: %{public}d, isFocused: %{public}d, reason: %{public}d, focusableOnShow: %{public}d",
9700 session->GetPersistentId(), session->GetPostProcessFocusState().isFocused_,
9701 session->GetPostProcessFocusState().reason_, session->IsFocusableOnShow());
9702 if (focusChanged) {
9703 session->ResetPostProcessFocusState();
9704 continue;
9705 }
9706 WSError ret = WSError::WS_DO_NOTHING;
9707 if (session->GetPostProcessFocusState().isFocused_) {
9708 if (session->GetPostProcessFocusState().reason_ == FocusChangeReason::SCB_START_APP) {
9709 ret = RequestSessionFocusImmediately(session->GetPersistentId());
9710 } else {
9711 ret = RequestSessionFocus(session->GetPersistentId(), true,
9712 session->GetPostProcessFocusState().reason_);
9713 }
9714 } else {
9715 ret = RequestSessionUnfocus(session->GetPersistentId(), session->GetPostProcessFocusState().reason_);
9716 }
9717 session->ResetPostProcessFocusState();
9718 // if succeed then end process
9719 if (ret == WSError::WS_OK) {
9720 focusChanged = true;
9721 }
9722 }
9723 }
9724
PostProcessProperty(uint32_t dirty)9725 void SceneSessionManager::PostProcessProperty(uint32_t dirty)
9726 {
9727 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::PostProcessProperty");
9728 if (dirty == static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA)) {
9729 // only trigger update avoid area
9730 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9731 for (auto& iter : sceneSessionMap_) {
9732 auto session = iter.second;
9733 if (session == nullptr) {
9734 continue;
9735 }
9736 session->PostProcessNotifyAvoidArea();
9737 }
9738 return;
9739 }
9740
9741 std::vector<std::pair<int32_t, sptr<SceneSession>>> processingSessions;
9742 {
9743 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9744 for (auto& iter : sceneSessionMap_) {
9745 auto session = iter.second;
9746 if (session == nullptr || !session->GetPostProcessProperty()) {
9747 continue;
9748 }
9749 processingSessions.push_back(iter);
9750 }
9751 }
9752
9753 for (auto iter = processingSessions.begin(); iter != processingSessions.end(); ++iter) {
9754 auto session = iter->second;
9755 if (session == nullptr) {
9756 WLOGFE("session is nullptr");
9757 continue;
9758 }
9759 TLOGD(WmsLogTag::WMS_PIPELINE, "id: %{public}d", session->GetPersistentId());
9760 UpdateForceHideState(session, session->GetSessionProperty(), true);
9761 HandleKeepScreenOn(session, session->IsKeepScreenOn());
9762 UpdatePrivateStateAndNotify(session->GetPersistentId());
9763 if (session->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9764 ProcessSubSessionForeground(session);
9765 }
9766 session->SetPostProcessProperty(false);
9767 }
9768
9769 // update avoid area
9770 {
9771 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9772 for (auto& iter : sceneSessionMap_) {
9773 auto session = iter.second;
9774 if (session == nullptr) {
9775 continue;
9776 }
9777 session->PostProcessNotifyAvoidArea();
9778 }
9779 }
9780 }
9781
9782 /** @note @window.hierarchy */
RaiseWindowToTop(int32_t persistentId)9783 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
9784 {
9785 WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
9786 auto isSaCall = SessionPermission::IsSACalling();
9787 if (!isSaCall) {
9788 WLOGFE("The interface only support for sa call");
9789 return WSError::WS_ERROR_INVALID_PERMISSION;
9790 }
9791 auto task = [this, persistentId]() {
9792 auto sceneSession = GetSceneSession(persistentId);
9793 if (sceneSession == nullptr) {
9794 WLOGFE("session is nullptr");
9795 return WSError::WS_ERROR_INVALID_SESSION;
9796 }
9797 if (!IsSessionVisibleForeground(sceneSession)) {
9798 WLOGFD("session is not visible!");
9799 return WSError::WS_DO_NOTHING;
9800 }
9801 FocusChangeReason reason = FocusChangeReason::MOVE_UP;
9802 RequestSessionFocus(persistentId, true, reason);
9803 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
9804 sceneSession->RaiseToAppTop();
9805 }
9806 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
9807 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
9808 WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
9809 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9810 }
9811 if (sceneSession == nullptr) {
9812 WLOGFE("parent session is nullptr");
9813 return WSError::WS_ERROR_INVALID_SESSION;
9814 }
9815 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9816 sceneSession->NotifyClick();
9817 return WSError::WS_OK;
9818 } else {
9819 WLOGFE("session is not app main window!");
9820 return WSError::WS_ERROR_INVALID_SESSION;
9821 }
9822 };
9823 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
9824 return WSError::WS_OK;
9825 }
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)9826 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
9827 {
9828 WLOGFI("from id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
9829 if (sourcePersistentId != focusedSessionId_) {
9830 WLOGFE("source session need be focused");
9831 return WSError::WS_ERROR_INVALID_OPERATION;
9832 }
9833 if (targetPersistentId == focusedSessionId_) {
9834 WLOGFE("target session has been focused");
9835 return WSError::WS_DO_NOTHING;
9836 }
9837 sptr<SceneSession> sourceSession = nullptr;
9838 WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
9839 if (ret != WSError::WS_OK) {
9840 return ret;
9841 }
9842 sptr<SceneSession> targetSession = nullptr;
9843 ret = GetAppMainSceneSession(targetSession, targetPersistentId);
9844 if (ret != WSError::WS_OK) {
9845 return ret;
9846 }
9847 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
9848 WLOGFE("verify bundle failed, source name is %{public}s but target name is %{public}s)",
9849 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
9850 return WSError::WS_ERROR_INVALID_CALLING;
9851 }
9852 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
9853 return WSError::WS_ERROR_INVALID_CALLING;
9854 }
9855 int32_t callingPid = IPCSkeleton::GetCallingPid();
9856 if (callingPid != targetSession->GetCallingPid()) {
9857 TLOGE(WmsLogTag::WMS_FOCUS, "permission denied, not call by the same process");
9858 return WSError::WS_ERROR_INVALID_CALLING;
9859 }
9860 targetSession->NotifyClick();
9861 FocusChangeReason reason = FocusChangeReason::CLIENT_REQUEST;
9862 return RequestSessionFocus(targetPersistentId, false, reason);
9863 }
9864
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)9865 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
9866 {
9867 sceneSession = GetSceneSession(persistentId);
9868 if (sceneSession == nullptr) {
9869 WLOGFE("session(%{public}d) is nullptr", persistentId);
9870 return WSError::WS_ERROR_INVALID_SESSION;
9871 }
9872 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
9873 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
9874 WLOGFE("session(%{public}d) is not main window or sub window", persistentId);
9875 return WSError::WS_ERROR_INVALID_CALLING;
9876 }
9877 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
9878 if (sceneSession == nullptr) {
9879 WLOGFE("session(%{public}d) parent is nullptr", persistentId);
9880 return WSError::WS_ERROR_INVALID_SESSION;
9881 }
9882 }
9883 return WSError::WS_OK;
9884 }
9885
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)9886 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
9887 const float scaleParam)
9888 {
9889 auto sceneSession = GetSceneSession(persistentId);
9890 if (!sceneSession) {
9891 WLOGFE("get scene session is nullptr");
9892 return nullptr;
9893 }
9894
9895 wptr<SceneSession> weakSceneSession(sceneSession);
9896 auto task = [this, persistentId, scaleParam, weakSceneSession]() {
9897 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
9898 auto scnSession = weakSceneSession.promote();
9899 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
9900 if (scnSession == nullptr) {
9901 WLOGFE("session is nullptr");
9902 return pixelMap;
9903 }
9904
9905 if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
9906 scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
9907 pixelMap = scnSession->Snapshot(false, scaleParam);
9908 }
9909 if (!pixelMap) {
9910 WLOGFI("get local snapshot pixelmap start");
9911 pixelMap = scnSession->GetSnapshotPixelMap(snapshotScale_, scaleParam);
9912 }
9913 return pixelMap;
9914 };
9915 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
9916 }
9917
GetSceneSessionMap()9918 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
9919 {
9920 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
9921 {
9922 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9923 retSceneSessionMap = sceneSessionMap_;
9924 }
9925 EraseIf(retSceneSessionMap, [this](const auto& pair) {
9926 if (pair.second == nullptr) {
9927 return true;
9928 }
9929
9930 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL) {
9931 if (pair.second->IsVisible()) {
9932 return false;
9933 }
9934 return true;
9935 }
9936
9937 if (pair.second->IsSystemInput()) {
9938 return false;
9939 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
9940 return false;
9941 }
9942
9943 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
9944 return true;
9945 }
9946 return false;
9947 });
9948 return retSceneSessionMap;
9949 }
9950
NotifyUpdateRectAfterLayout()9951 void SceneSessionManager::NotifyUpdateRectAfterLayout()
9952 {
9953 auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
9954 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
9955 if (transactionController) {
9956 rsTransaction = transactionController->GetRSTransaction();
9957 }
9958 auto task = [this, rsTransaction]() {
9959 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
9960 for (auto& iter: sceneSessionMap_) {
9961 auto sceneSession = iter.second;
9962 if (sceneSession && sceneSession->IsDirtyWindow()) {
9963 sceneSession->NotifyClientToUpdateRect("AfterLayoutFromPersistentTask", rsTransaction);
9964 }
9965 }
9966 };
9967 // need sync task since animation transcation need
9968 return taskScheduler_->PostAsyncTask(task);
9969 }
9970
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)9971 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
9972 {
9973 if (!SessionPermission::IsSystemCalling()) {
9974 WLOGFE("GetVisibilityWindowInfo permission denied!");
9975 return WMError::WM_ERROR_NOT_SYSTEM_APP;
9976 }
9977 auto task = [this, &infos]() {
9978 for (auto [surfaceId, _] : lastVisibleData_) {
9979 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
9980 if (session == nullptr) {
9981 continue;
9982 }
9983 WSRect hostRect = session->GetSessionRect();
9984 Rect rect = {hostRect.posX_, hostRect.posY_,
9985 static_cast<uint32_t>(hostRect.width_), static_cast<uint32_t>(hostRect.height_)};
9986 auto windowStatus = GetWindowStatus(session->GetWindowMode(), session->GetSessionState(),
9987 session->GetSessionProperty());
9988 infos.emplace_back(sptr<WindowVisibilityInfo>::MakeSptr(session->GetWindowId(), session->GetCallingPid(),
9989 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType(), windowStatus, rect,
9990 session->GetSessionInfo().bundleName_, session->GetSessionInfo().abilityName_,
9991 session->IsFocused()));
9992 }
9993 return WMError::WM_OK;
9994 };
9995 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
9996 }
9997
GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t,uint32_t>> & windowVisibilityInfos)9998 void SceneSessionManager::GetAllWindowVisibilityInfos(std::vector<std::pair<int32_t, uint32_t>>& windowVisibilityInfos)
9999 {
10000 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10001 for (const auto& [id, session] : sceneSessionMap_) {
10002 if (session == nullptr) {
10003 continue;
10004 }
10005 uint32_t visibilityState = static_cast<uint32_t>(session->GetVisibilityState());
10006 windowVisibilityInfos.push_back(std::make_pair(id, visibilityState));
10007 }
10008 }
10009
FlushWindowInfoToMMI(const bool forceFlush)10010 void SceneSessionManager::FlushWindowInfoToMMI(const bool forceFlush)
10011 {
10012 auto task = [this, forceFlush] {
10013 if (isUserBackground_) {
10014 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background, no need to flush info to MMI");
10015 return;
10016 }
10017 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
10018 SceneInputManager::GetInstance().FlushDisplayInfoToMMI(forceFlush);
10019 };
10020 taskScheduler_->PostAsyncTask(task);
10021 }
10022
GetExtensionWindowIds(const sptr<IRemoteObject> & token,int32_t & persistentId,int32_t & parentId)10023 bool SceneSessionManager::GetExtensionWindowIds(const sptr<IRemoteObject>& token, int32_t& persistentId,
10024 int32_t& parentId)
10025 {
10026 // This function should be called in task
10027 auto iter = extSessionInfoMap_.find(token);
10028 if (iter == extSessionInfoMap_.end()) {
10029 return false;
10030 }
10031 persistentId = iter->second.persistentId;
10032 parentId = iter->second.parentId;
10033 return true;
10034 }
10035
DestroyExtensionSession(const sptr<IRemoteObject> & remoteExtSession)10036 void SceneSessionManager::DestroyExtensionSession(const sptr<IRemoteObject>& remoteExtSession)
10037 {
10038 auto task = [this, remoteExtSession]() {
10039 auto iter = remoteExtSessionMap_.find(remoteExtSession);
10040 if (iter == remoteExtSessionMap_.end()) {
10041 TLOGI(WmsLogTag::WMS_UIEXT, "Invalid remoteExtSession or already destroyed");
10042 return;
10043 }
10044 auto abilityToken = iter->second;
10045 int32_t persistentId = INVALID_SESSION_ID;
10046 int32_t parentId = INVALID_SESSION_ID;
10047 if (!GetExtensionWindowIds(abilityToken, persistentId, parentId)) {
10048 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10049 return;
10050 }
10051
10052 TLOGI(WmsLogTag::WMS_UIEXT, "DestroyExtensionSession: persistentId=%{public}d, parentId=%{public}d",
10053 persistentId, parentId);
10054 auto sceneSession = GetSceneSession(parentId);
10055 if (sceneSession != nullptr) {
10056 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10057 sceneSession->RemoveExtWindowFlags(persistentId);
10058 if (oldFlags.hideNonSecureWindowsFlag) {
10059 HandleSecureSessionShouldHide(sceneSession);
10060 }
10061 if (oldFlags.waterMarkFlag) {
10062 CheckAndNotifyWaterMarkChangedResult();
10063 }
10064 if (oldFlags.privacyModeFlag) {
10065 UpdatePrivateStateAndNotify(parentId);
10066 }
10067 sceneSession->RemoveModalUIExtension(persistentId);
10068 sceneSession->RemoveUIExtSurfaceNodeId(persistentId);
10069 sceneSession->RemoveExtensionTokenInfo(abilityToken);
10070 } else {
10071 ExtensionWindowFlags actions;
10072 actions.SetAllActive();
10073 HandleSpecialExtWindowFlagsChange(persistentId, ExtensionWindowFlags(), actions);
10074 }
10075 extSessionInfoMap_.erase(iter->second);
10076 remoteExtSessionMap_.erase(iter);
10077 };
10078 taskScheduler_->PostAsyncTask(task, "DestroyExtensionSession");
10079 }
10080
UpdateModalExtensionRect(const sptr<IRemoteObject> & token,Rect rect)10081 void SceneSessionManager::UpdateModalExtensionRect(const sptr<IRemoteObject>& token, Rect rect)
10082 {
10083 auto pid = IPCSkeleton::GetCallingRealPid();
10084 auto task = [this, token, pid, rect]() {
10085 int32_t persistentId = INVALID_SESSION_ID;
10086 int32_t parentId = INVALID_SESSION_ID;
10087 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10088 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10089 return;
10090 }
10091 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid=%{public}d, persistentId=%{public}d, "
10092 "parentId=%{public}d, rect:[%{public}d %{public}d %{public}d %{public}d]",
10093 pid, persistentId, parentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10094 auto parentSession = GetSceneSession(parentId);
10095 if (parentSession) {
10096 auto parentTransX = parentSession->GetSessionGlobalRect().posX_ - parentSession->GetSessionRect().posX_;
10097 auto parentTransY = parentSession->GetSessionGlobalRect().posY_ - parentSession->GetSessionRect().posY_;
10098 Rect globalRect = { rect.posX_ + parentTransX, rect.posY_ + parentTransY, rect.width_, rect.height_ };
10099 ExtensionWindowEventInfo extensionInfo { persistentId, pid, globalRect, rect, true };
10100 TLOGNI(WmsLogTag::WMS_UIEXT, "UpdateModalExtensionRect: pid: %{public}d, persistentId: %{public}d, "
10101 "parentId: %{public}d, rect: %{public}s, globalRect: %{public}s, parentGlobalRect: %{public}s",
10102 pid, persistentId, parentId, rect.ToString().c_str(), globalRect.ToString().c_str(),
10103 parentSession->GetSessionGlobalRect().ToString().c_str());
10104 parentSession->UpdateModalUIExtension(extensionInfo);
10105 }
10106 };
10107 taskScheduler_->PostAsyncTask(task, "UpdateModalExtensionRect");
10108 }
10109
ProcessModalExtensionPointDown(const sptr<IRemoteObject> & token,int32_t posX,int32_t posY)10110 void SceneSessionManager::ProcessModalExtensionPointDown(const sptr<IRemoteObject>& token, int32_t posX, int32_t posY)
10111 {
10112 auto pid = IPCSkeleton::GetCallingRealPid();
10113 auto task = [this, token, pid, posX, posY]() {
10114 int32_t persistentId = INVALID_SESSION_ID;
10115 int32_t parentId = INVALID_SESSION_ID;
10116 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10117 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10118 return;
10119 }
10120 TLOGI(WmsLogTag::WMS_UIEXT, "ProcessModalExtensionPointDown: pid=%{public}d, persistentId=%{public}d, "
10121 "parentId=%{public}d", pid, persistentId, parentId);
10122 auto parentSession = GetSceneSession(parentId);
10123 if (parentSession) {
10124 auto modalUIExtensionEventInfo = parentSession->GetLastModalUIExtensionEventInfo();
10125 if (modalUIExtensionEventInfo && modalUIExtensionEventInfo.value().pid == pid &&
10126 modalUIExtensionEventInfo.value().persistentId == persistentId) {
10127 parentSession->ProcessPointDownSession(posX, posY);
10128 }
10129 }
10130 };
10131 taskScheduler_->PostAsyncTask(task, "ProcessModalExtensionPointDown");
10132 }
10133
AddExtensionWindowStageToSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token,uint64_t surfaceNodeId)10134 void SceneSessionManager::AddExtensionWindowStageToSCB(const sptr<ISessionStage>& sessionStage,
10135 const sptr<IRemoteObject>& token, uint64_t surfaceNodeId)
10136 {
10137 auto pid = IPCSkeleton::GetCallingRealPid();
10138 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
10139 auto task = [this, sessionStage, token, surfaceNodeId, pid, callingTokenId]() {
10140 if (sessionStage == nullptr || token == nullptr) {
10141 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10142 return;
10143 }
10144 auto remoteExtSession = sessionStage->AsObject();
10145 if (remoteExtSession == nullptr) {
10146 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10147 return;
10148 }
10149 if (extensionDeath_ == nullptr) {
10150 TLOGE(WmsLogTag::WMS_UIEXT, "failed to create death recipient");
10151 return;
10152 }
10153 if (!remoteExtSession->AddDeathRecipient(extensionDeath_)) {
10154 TLOGE(WmsLogTag::WMS_UIEXT, "failed to add death recipient");
10155 return;
10156 }
10157
10158 AAFwk::UIExtensionSessionInfo info;
10159 AAFwk::AbilityManagerClient::GetInstance()->GetUIExtensionSessionInfo(token, info);
10160 if (info.persistentId == INVALID_SESSION_ID || info.hostWindowId == INVALID_SESSION_ID) {
10161 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension session info failed");
10162 return;
10163 }
10164
10165 int32_t persistentId = info.persistentId;
10166 int32_t parentId = static_cast<int32_t>(info.hostWindowId);
10167 UIExtensionUsage usage = static_cast<UIExtensionUsage>(info.uiExtensionUsage);
10168 TLOGI(WmsLogTag::WMS_UIEXT, "AddExtensionWindowStageToSCB: persistentId=%{public}d, parentId=%{public}d, "
10169 "usage=%{public}u, surfaceNodeId=%{public}" PRIu64", pid=%{public}d", persistentId, parentId, usage,
10170 surfaceNodeId, pid);
10171
10172 remoteExtSessionMap_.insert(std::make_pair(remoteExtSession, token));
10173 extSessionInfoMap_.insert(std::make_pair(token, ExtensionWindowAbilityInfo{ persistentId, parentId, usage }));
10174
10175 auto parentSession = GetSceneSession(parentId);
10176 if (!parentSession) {
10177 TLOGNI(WmsLogTag::WMS_UIEXT, "no parent session for %{public}d", persistentId);
10178 return;
10179 }
10180
10181 UIExtensionTokenInfo tokenInfo;
10182 tokenInfo.abilityToken = token;
10183 tokenInfo.callingTokenId = callingTokenId;
10184 tokenInfo.canShowOnLockScreen = IsUIExtCanShowOnLockScreen(info.elementName, callingTokenId,
10185 info.extensionAbilityType);
10186 parentSession->AddExtensionTokenInfo(tokenInfo);
10187 parentSession->AddUIExtSurfaceNodeId(surfaceNodeId, persistentId);
10188 if (usage == UIExtensionUsage::MODAL) {
10189 ExtensionWindowEventInfo extensionInfo {
10190 .persistentId = persistentId,
10191 .pid = pid,
10192 };
10193 parentSession->AddModalUIExtension(extensionInfo);
10194 }
10195 };
10196 taskScheduler_->PostAsyncTask(task, "AddExtensionWindowStageToSCB");
10197 }
10198
RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage> & sessionStage,const sptr<IRemoteObject> & token)10199 void SceneSessionManager::RemoveExtensionWindowStageFromSCB(const sptr<ISessionStage>& sessionStage,
10200 const sptr<IRemoteObject>& token)
10201 {
10202 TLOGI(WmsLogTag::WMS_UIEXT, "called");
10203 auto task = [this, sessionStage, token]() {
10204 if (sessionStage == nullptr || token == nullptr) {
10205 TLOGE(WmsLogTag::WMS_UIEXT, "input is nullptr");
10206 return;
10207 }
10208 auto remoteExtSession = sessionStage->AsObject();
10209 if (remoteExtSession == nullptr) {
10210 TLOGE(WmsLogTag::WMS_UIEXT, "sessionStage object is nullptr");
10211 return;
10212 }
10213 auto iter = remoteExtSessionMap_.find(remoteExtSession);
10214 if (iter == remoteExtSessionMap_.end() || iter->second != token) {
10215 TLOGE(WmsLogTag::WMS_UIEXT, "token not match");
10216 return;
10217 }
10218
10219 DestroyExtensionSession(remoteExtSession);
10220 };
10221 taskScheduler_->PostAsyncTask(task, "RemoveExtensionWindowStageFromSCB");
10222 }
10223
CalculateCombinedExtWindowFlags()10224 void SceneSessionManager::CalculateCombinedExtWindowFlags()
10225 {
10226 // Only correct when each flag is true when active, and once a uiextension is active, the host is active
10227 combinedExtWindowFlags_.bitData = 0;
10228 for (const auto& iter: extWindowFlagsMap_) {
10229 combinedExtWindowFlags_.bitData |= iter.second.bitData;
10230 }
10231 specialExtWindowHasPrivacyMode_.store(combinedExtWindowFlags_.privacyModeFlag);
10232 }
10233
UpdateSpecialExtWindowFlags(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10234 void SceneSessionManager::UpdateSpecialExtWindowFlags(int32_t persistentId, ExtensionWindowFlags flags,
10235 ExtensionWindowFlags actions)
10236 {
10237 auto iter = extWindowFlagsMap_.find(persistentId);
10238 // Each flag is false when inactive, 0 means all flags are inactive
10239 auto oldFlags = iter != extWindowFlagsMap_.end() ? iter->second : ExtensionWindowFlags();
10240 ExtensionWindowFlags newFlags((flags.bitData & actions.bitData) | (oldFlags.bitData & ~actions.bitData));
10241 if (newFlags.bitData == 0) {
10242 extWindowFlagsMap_.erase(persistentId);
10243 } else {
10244 extWindowFlagsMap_[persistentId] = newFlags;
10245 }
10246 CalculateCombinedExtWindowFlags();
10247 }
10248
HideNonSecureFloatingWindows()10249 void SceneSessionManager::HideNonSecureFloatingWindows()
10250 {
10251 bool shouldHide = false;
10252 {
10253 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10254 for (const auto& iter: sceneSessionMap_) {
10255 auto& session = iter.second;
10256 if (session && session->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag) {
10257 shouldHide = true;
10258 break;
10259 }
10260 }
10261 }
10262 if (combinedExtWindowFlags_.hideNonSecureWindowsFlag) {
10263 TLOGI(WmsLogTag::WMS_UIEXT, "SCB UIExtension hide non-secure windows");
10264 shouldHide = true;
10265 }
10266 if (shouldHide == shouldHideNonSecureFloatingWindows_.load()) {
10267 return;
10268 }
10269
10270 shouldHideNonSecureFloatingWindows_.store(shouldHide);
10271 for (const auto& [persistentId, session] : nonSystemFloatSceneSessionMap_) {
10272 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
10273 session->NotifyForceHideChange(shouldHide);
10274 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10275 session->GetWindowName().c_str(), persistentId, shouldHide);
10276 }
10277 }
10278 }
10279
HideNonSecureSubWindows(const sptr<SceneSession> & sceneSession)10280 void SceneSessionManager::HideNonSecureSubWindows(const sptr<SceneSession>& sceneSession)
10281 {
10282 // don't let sub-window show when switching secure host window to background
10283 if (!sceneSession->IsSessionForeground()) {
10284 return;
10285 }
10286
10287 auto parentId = sceneSession->GetPersistentId();
10288 bool shouldHide = sceneSession->GetCombinedExtWindowFlags().hideNonSecureWindowsFlag;
10289 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10290 for (const auto& [persistentId, session] : sceneSessionMap_) {
10291 if (!session) {
10292 continue;
10293 }
10294 auto property = session->GetSessionProperty();
10295 if (!property || property->GetParentPersistentId() != parentId) {
10296 continue;
10297 }
10298
10299 if (SessionHelper::IsNonSecureToUIExtension(property->GetWindowType()) && !session->IsSystemSpecificSession()) {
10300 session->NotifyForceHideChange(shouldHide);
10301 TLOGI(WmsLogTag::WMS_UIEXT, "name=%{public}s, persistentId=%{public}d, shouldHide=%{public}u",
10302 session->GetWindowName().c_str(), session->GetPersistentId(), shouldHide);
10303 }
10304 }
10305 }
10306
HandleSecureSessionShouldHide(const sptr<SceneSession> & sceneSession)10307 WSError SceneSessionManager::HandleSecureSessionShouldHide(const sptr<SceneSession>& sceneSession)
10308 {
10309 if (sceneSession == nullptr) {
10310 TLOGE(WmsLogTag::WMS_UIEXT, "sceneSession is nullptr");
10311 return WSError::WS_ERROR_INVALID_SESSION;
10312 }
10313
10314 HideNonSecureFloatingWindows();
10315 HideNonSecureSubWindows(sceneSession);
10316 return WSError::WS_OK;
10317 }
10318
HandleSpecialExtWindowFlagsChange(int32_t persistentId,ExtensionWindowFlags flags,ExtensionWindowFlags actions)10319 void SceneSessionManager::HandleSpecialExtWindowFlagsChange(int32_t persistentId, ExtensionWindowFlags flags,
10320 ExtensionWindowFlags actions)
10321 {
10322 UpdateSpecialExtWindowFlags(persistentId, flags, actions);
10323 if (actions.waterMarkFlag) {
10324 CheckAndNotifyWaterMarkChangedResult();
10325 }
10326 if (actions.hideNonSecureWindowsFlag) {
10327 HideNonSecureFloatingWindows();
10328 }
10329 if (actions.privacyModeFlag) {
10330 UpdatePrivateStateAndNotifyForAllScreens();
10331 }
10332 }
10333
AddOrRemoveSecureSession(int32_t persistentId,bool shouldHide)10334 WSError SceneSessionManager::AddOrRemoveSecureSession(int32_t persistentId, bool shouldHide)
10335 {
10336 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d, shouldHide=%{public}u", persistentId, shouldHide);
10337 if (!SessionPermission::IsSystemCalling()) {
10338 TLOGE(WmsLogTag::WMS_UIEXT, "HideNonSecureWindows permission denied!");
10339 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10340 }
10341 const auto callingPid = IPCSkeleton::GetCallingRealPid();
10342 auto task = [this, persistentId, shouldHide, callingPid]() {
10343 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10344 auto iter = sceneSessionMap_.find(persistentId);
10345 if (iter == sceneSessionMap_.end()) {
10346 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Session with persistentId %{public}d not found",
10347 persistentId);
10348 return WSError::WS_ERROR_INVALID_SESSION;
10349 }
10350 auto sceneSession = iter->second;
10351 if (sceneSession == nullptr) {
10352 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: sceneSession is nullptr.");
10353 return WSError::WS_ERROR_NULLPTR;
10354 }
10355 if (callingPid != sceneSession->GetCallingPid()) {
10356 TLOGE(WmsLogTag::WMS_UIEXT, "AddOrRemoveSecureSession: Permission denied");
10357 return WSError::WS_ERROR_INVALID_PERMISSION;
10358 }
10359 sceneSession->SetShouldHideNonSecureWindows(shouldHide);
10360 return HandleSecureSessionShouldHide(sceneSession);
10361 };
10362
10363 taskScheduler_->PostAsyncTask(task, "AddOrRemoveSecureSession");
10364 return WSError::WS_OK;
10365 }
10366
CheckExtWindowFlagsPermission(ExtensionWindowFlags & actions) const10367 WSError SceneSessionManager::CheckExtWindowFlagsPermission(ExtensionWindowFlags& actions) const
10368 {
10369 auto ret = WSError::WS_OK;
10370 bool needSystemCalling = actions.hideNonSecureWindowsFlag || actions.waterMarkFlag;
10371 if (needSystemCalling && !SessionPermission::IsSystemCalling()) {
10372 actions.hideNonSecureWindowsFlag = false;
10373 actions.waterMarkFlag = false;
10374 TLOGE(WmsLogTag::WMS_UIEXT, "system calling permission denied!");
10375 ret = WSError::WS_ERROR_NOT_SYSTEM_APP;
10376 }
10377 auto needPrivacyWindow = actions.privacyModeFlag;
10378 if (needPrivacyWindow && !SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
10379 actions.privacyModeFlag = false;
10380 TLOGE(WmsLogTag::WMS_UIEXT, "privacy window permission denied!");
10381 ret = WSError::WS_ERROR_INVALID_PERMISSION;
10382 }
10383 return ret;
10384 }
10385
UpdateExtWindowFlags(const sptr<IRemoteObject> & token,uint32_t extWindowFlags,uint32_t extWindowActions)10386 WSError SceneSessionManager::UpdateExtWindowFlags(const sptr<IRemoteObject>& token, uint32_t extWindowFlags,
10387 uint32_t extWindowActions)
10388 {
10389 ExtensionWindowFlags actions(extWindowActions);
10390 auto ret = CheckExtWindowFlagsPermission(actions);
10391 if (actions.bitData == 0) {
10392 return ret;
10393 }
10394
10395 ExtensionWindowFlags flags(extWindowFlags);
10396 auto task = [this, token, flags, actions]() {
10397 int32_t persistentId = INVALID_SESSION_ID;
10398 int32_t parentId = INVALID_SESSION_ID;
10399 if (!GetExtensionWindowIds(token, persistentId, parentId)) {
10400 TLOGE(WmsLogTag::WMS_UIEXT, "Get UIExtension window ids by token failed");
10401 return WSError::WS_ERROR_INVALID_OPERATION;
10402 }
10403
10404 TLOGI(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: parentId=%{public}d, persistentId=%{public}d, "
10405 "extWindowFlags=%{public}d, actions=%{public}d", parentId, persistentId, flags.bitData, actions.bitData);
10406 auto sceneSession = GetSceneSession(parentId);
10407 if (sceneSession == nullptr) {
10408 TLOGD(WmsLogTag::WMS_UIEXT, "UpdateExtWindowFlags: Parent session with persistentId %{public}d not found",
10409 parentId);
10410 HandleSpecialExtWindowFlagsChange(persistentId, flags, actions);
10411 return WSError::WS_OK;
10412 }
10413
10414 auto oldFlags = sceneSession->GetCombinedExtWindowFlags();
10415 sceneSession->UpdateExtWindowFlags(persistentId, flags, actions);
10416 auto newFlags = sceneSession->GetCombinedExtWindowFlags();
10417 if (oldFlags.hideNonSecureWindowsFlag != newFlags.hideNonSecureWindowsFlag) {
10418 HandleSecureSessionShouldHide(sceneSession);
10419 }
10420 if (oldFlags.waterMarkFlag != newFlags.waterMarkFlag) {
10421 CheckAndNotifyWaterMarkChangedResult();
10422 }
10423 if (oldFlags.privacyModeFlag != newFlags.privacyModeFlag) {
10424 UpdatePrivateStateAndNotify(parentId);
10425 }
10426 return WSError::WS_OK;
10427 };
10428
10429 taskScheduler_->PostAsyncTask(task, "UpdateExtWindowFlags");
10430 return ret;
10431 }
10432
GetHostWindowRect(int32_t hostWindowId,Rect & rect)10433 WSError SceneSessionManager::GetHostWindowRect(int32_t hostWindowId, Rect& rect)
10434 {
10435 TLOGI(WmsLogTag::WMS_UIEXT, "hostWindowId:%{public}d", hostWindowId);
10436 if (!SessionPermission::IsSystemCalling()) {
10437 TLOGE(WmsLogTag::WMS_UIEXT, "GetHostWindowRect permission denied!");
10438 return WSError::WS_ERROR_NOT_SYSTEM_APP;
10439 }
10440 auto task = [this, hostWindowId, &rect]() {
10441 auto sceneSession = GetSceneSession(hostWindowId);
10442 if (sceneSession == nullptr) {
10443 TLOGE(WmsLogTag::WMS_UIEXT, "Session with persistentId %{public}d not found", hostWindowId);
10444 return WSError::WS_ERROR_INVALID_SESSION;
10445 }
10446 WSRect hostRect = sceneSession->GetSessionRect();
10447 rect = {hostRect.posX_, hostRect.posY_, hostRect.width_, hostRect.height_};
10448 return WSError::WS_OK;
10449 };
10450 taskScheduler_->PostSyncTask(task, "GetHostWindowRect");
10451 return WSError::WS_OK;
10452 }
10453
ReclaimPurgeableCleanMem()10454 int32_t SceneSessionManager::ReclaimPurgeableCleanMem()
10455 {
10456 #ifdef MEMMGR_WINDOW_ENABLE
10457 return Memory::MemMgrClient::GetInstance().ReclaimPurgeableCleanMem();
10458 #else
10459 return -1;
10460 #endif
10461 }
10462
IsVectorSame(const std::vector<VisibleWindowNumInfo> & lastInfo,const std::vector<VisibleWindowNumInfo> & currentInfo)10463 bool SceneSessionManager::IsVectorSame(const std::vector<VisibleWindowNumInfo>& lastInfo,
10464 const std::vector<VisibleWindowNumInfo>& currentInfo)
10465 {
10466 if (lastInfo.size() != currentInfo.size()) {
10467 WLOGFE("last and current info is not Same");
10468 return false;
10469 }
10470 int sizeOfLastInfo = static_cast<int>(lastInfo.size());
10471 for (int i = 0; i < sizeOfLastInfo; i++) {
10472 if (lastInfo[i].displayId != currentInfo[i].displayId ||
10473 lastInfo[i].visibleWindowNum != currentInfo[i].visibleWindowNum) {
10474 WLOGFE("last and current visible window num is not Same");
10475 return false;
10476 }
10477 }
10478 return true;
10479 }
10480
CacVisibleWindowNum()10481 void SceneSessionManager::CacVisibleWindowNum()
10482 {
10483 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10484 {
10485 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10486 sceneSessionMapCopy = sceneSessionMap_;
10487 }
10488 std::vector<VisibleWindowNumInfo> visibleWindowNumInfo;
10489 bool isFullScreen = true;
10490 for (const auto& elem : sceneSessionMapCopy) {
10491 auto curSession = elem.second;
10492 if (curSession == nullptr) {
10493 continue;
10494 }
10495 bool isTargetWindow = (WindowHelper::IsMainWindow(curSession->GetWindowType()) ||
10496 curSession->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER);
10497 if (!isTargetWindow || curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10498 continue;
10499 }
10500
10501 bool isWindowVisible = curSession->GetRSVisible();
10502 if (isWindowVisible) {
10503 auto windowMode = curSession->GetWindowMode();
10504 if (windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
10505 windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
10506 windowMode == WindowMode::WINDOW_MODE_FLOATING || windowMode == WindowMode::WINDOW_MODE_PIP) {
10507 isFullScreen = false;
10508 }
10509 int32_t displayId = static_cast<int32_t>(curSession->GetSessionProperty()->GetDisplayId());
10510 auto it = std::find_if(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10511 [=](const VisibleWindowNumInfo& info) {
10512 return (static_cast<int32_t>(info.displayId)) == displayId;
10513 });
10514 if (it == visibleWindowNumInfo.end()) {
10515 visibleWindowNumInfo.push_back({displayId, 1});
10516 } else {
10517 it->visibleWindowNum++;
10518 }
10519 }
10520 }
10521 if (isFullScreen) {
10522 std::for_each(visibleWindowNumInfo.begin(), visibleWindowNumInfo.end(),
10523 [](auto& info) { info.visibleWindowNum = 1; });
10524 }
10525 std::unique_lock<std::shared_mutex> lock(lastInfoMutex_);
10526 if (visibleWindowNumInfo.size() > 0 && !IsVectorSame(lastInfo_, visibleWindowNumInfo)) {
10527 SessionManagerAgentController::GetInstance().UpdateVisibleWindowNum(visibleWindowNumInfo);
10528 lastInfo_ = visibleWindowNumInfo;
10529 }
10530 }
10531
ReportWindowProfileInfos()10532 void SceneSessionManager::ReportWindowProfileInfos()
10533 {
10534 enum class WindowVisibleState : int32_t {
10535 FOCUSBLE = 0,
10536 VISIBLE,
10537 MINIMIZED,
10538 OCCLUSION
10539 };
10540 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
10541 {
10542 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10543 sceneSessionMapCopy = sceneSessionMap_;
10544 }
10545 auto focusWindowId = GetFocusedSessionId();
10546 for (const auto& elem : sceneSessionMapCopy) {
10547 auto curSession = elem.second;
10548 if (curSession == nullptr || curSession->GetSessionInfo().isSystem_ ||
10549 curSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
10550 continue;
10551 }
10552 WindowProfileInfo windowProfileInfo;
10553 windowProfileInfo.bundleName = curSession->GetSessionInfo().bundleName_;
10554 windowProfileInfo.windowLocatedScreen = static_cast<int32_t>(
10555 curSession->GetSessionProperty()->GetDisplayId());
10556 windowProfileInfo.windowSceneMode = static_cast<int32_t>(curSession->GetWindowMode());
10557 if (focusWindowId == static_cast<int32_t>(curSession->GetWindowId())) {
10558 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::FOCUSBLE);
10559 } else if (curSession->GetSessionState() == SessionState::STATE_BACKGROUND) {
10560 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::MINIMIZED);
10561 } else if (!curSession->GetRSVisible()) {
10562 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::OCCLUSION);
10563 } else {
10564 windowProfileInfo.windowVisibleState = static_cast<int32_t>(WindowVisibleState::VISIBLE);
10565 }
10566 WindowInfoReporter::GetInstance().ReportWindowProfileInfo(windowProfileInfo);
10567 WLOGFD("ReportWindowProfileInfo, bundleName:%{public}s, windowVisibleState:%{public}d, "
10568 "windowLocatedScreen:%{public}d, windowSceneMode:%{public}d",
10569 windowProfileInfo.bundleName.c_str(), windowProfileInfo.windowVisibleState,
10570 windowProfileInfo.windowLocatedScreen, windowProfileInfo.windowSceneMode);
10571 }
10572 }
10573
GetCustomDecorHeight(int32_t persistentId)10574 int32_t SceneSessionManager::GetCustomDecorHeight(int32_t persistentId)
10575 {
10576 int32_t height = 0;
10577 auto sceneSession = GetSceneSession(persistentId);
10578 if (sceneSession == nullptr) {
10579 TLOGE(WmsLogTag::WMS_LAYOUT, "Session with persistentId %{public}d not found", persistentId);
10580 return 0;
10581 }
10582 height = sceneSession->GetCustomDecorHeight();
10583 TLOGD(WmsLogTag::WMS_LAYOUT, "GetCustomDecorHeight: %{public}d", height);
10584 return height;
10585 }
10586
removeFailRecoveredSession()10587 void SceneSessionManager::removeFailRecoveredSession()
10588 {
10589 for (const auto& persistentId : failRecoveredPersistentIdSet_) {
10590 auto sceneSession = GetSceneSession(persistentId);
10591 if (sceneSession == nullptr) {
10592 TLOGE(WmsLogTag::WMS_RECOVER, "Session is nullptr, persistentId = %{public}d", persistentId);
10593 continue;
10594 }
10595 if (!sceneSession->IsRecovered()) {
10596 TLOGW(WmsLogTag::WMS_RECOVER, "not recovered session persistentId = %{public}d", persistentId);
10597 continue;
10598 }
10599 const auto &scnSessionInfo = SetAbilitySessionInfo(sceneSession);
10600 if (!scnSessionInfo) {
10601 TLOGW(WmsLogTag::WMS_RECOVER, "scnSessionInfo is nullptr,persistentId = %{public}d", persistentId);
10602 continue;
10603 }
10604 TLOGI(WmsLogTag::WMS_RECOVER, "remove recover failed persistentId = %{public}d", persistentId);
10605 sceneSession->NotifySessionExceptionInner(scnSessionInfo, true);
10606 }
10607 failRecoveredPersistentIdSet_.clear();
10608 }
10609
GetDisplayRegion(DisplayId displayId)10610 std::shared_ptr<SkRegion> SceneSessionManager::GetDisplayRegion(DisplayId displayId)
10611 {
10612 if (displayRegionMap_.find(displayId) != displayRegionMap_.end()) {
10613 return std::make_shared<SkRegion>(displayRegionMap_[displayId]->getBounds());
10614 }
10615 TLOGI(WmsLogTag::WMS_MAIN, "can not find display info from mem, sync dispslay region from dms.");
10616 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(displayId);
10617 if (display == nullptr) {
10618 TLOGE(WmsLogTag::WMS_MAIN, "get display object failed of display: %{public}" PRIu64, displayId);
10619 return nullptr;
10620 }
10621 auto displayInfo = display->GetDisplayInfo();
10622 if (displayInfo == nullptr) {
10623 TLOGE(WmsLogTag::WMS_MAIN, "get display info failed of display: %{public}" PRIu64, displayId);
10624 return nullptr;
10625 }
10626 int32_t displayWidth = displayInfo->GetWidth();
10627 int32_t displayHeight = displayInfo->GetHeight();
10628 if (displayWidth == 0 || displayHeight == 0) {
10629 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10630 return nullptr;
10631 }
10632
10633 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10634 auto region = std::make_shared<SkRegion>(rect);
10635 displayRegionMap_[displayId] = region;
10636 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10637 return std::make_shared<SkRegion>(rect);
10638 }
10639
UpdateDisplayRegion(const sptr<DisplayInfo> & displayInfo)10640 void SceneSessionManager::UpdateDisplayRegion(const sptr<DisplayInfo>& displayInfo)
10641 {
10642 if (displayInfo == nullptr) {
10643 TLOGE(WmsLogTag::WMS_MAIN, "update display region failed, displayInfo is nullptr.");
10644 return;
10645 }
10646 auto displayId = displayInfo->GetDisplayId();
10647 int32_t displayWidth = displayInfo->GetWidth();
10648 int32_t displayHeight = displayInfo->GetHeight();
10649 if (displayWidth == 0 || displayHeight == 0) {
10650 TLOGE(WmsLogTag::WMS_MAIN, "invalid display size of display: %{public}" PRIu64, displayId);
10651 return;
10652 }
10653 SkIRect rect {.fLeft = 0, .fTop = 0, .fRight = displayWidth, .fBottom = displayHeight};
10654 auto region = std::make_shared<SkRegion>(rect);
10655 displayRegionMap_[displayId] = region;
10656 TLOGI(WmsLogTag::WMS_MAIN, "update display region to w = %{public}d, h = %{public}d", displayWidth, displayHeight);
10657 }
10658
GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>> & sceneSessionList)10659 void SceneSessionManager::GetAllSceneSessionForAccessibility(std::vector<sptr<SceneSession>>& sceneSessionList)
10660 {
10661 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
10662 for (const auto& item : sceneSessionMap_) {
10663 auto sceneSession = item.second;
10664 if (sceneSession == nullptr) {
10665 continue;
10666 }
10667 if (Session::IsScbCoreEnabled()) {
10668 if (!sceneSession->IsVisibleForAccessibility()) {
10669 continue;
10670 }
10671 } else {
10672 if (!sceneSession->IsVisibleForAccessibility() || !IsSessionVisible(sceneSession)) {
10673 continue;
10674 }
10675 }
10676 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos ||
10677 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos ||
10678 sceneSession->GetSessionInfo().bundleName_.find("SCBGestureTopBar") != std::string::npos) {
10679 continue;
10680 }
10681 sceneSessionList.push_back(sceneSession);
10682 }
10683 }
10684
FillAccessibilityInfo(std::vector<sptr<SceneSession>> & sceneSessionList,std::vector<sptr<AccessibilityWindowInfo>> & accessibilityInfo)10685 void SceneSessionManager::FillAccessibilityInfo(std::vector<sptr<SceneSession>>& sceneSessionList,
10686 std::vector<sptr<AccessibilityWindowInfo>>& accessibilityInfo)
10687 {
10688 for (const auto& sceneSession : sceneSessionList) {
10689 if (!FillWindowInfo(accessibilityInfo, sceneSession)) {
10690 TLOGW(WmsLogTag::WMS_MAIN, "fill accessibilityInfo failed");
10691 }
10692 }
10693 }
10694
FilterSceneSessionCovered(std::vector<sptr<SceneSession>> & sceneSessionList)10695 void SceneSessionManager::FilterSceneSessionCovered(std::vector<sptr<SceneSession>>& sceneSessionList)
10696 {
10697 std::sort(sceneSessionList.begin(), sceneSessionList.end(), [](sptr<SceneSession> a, sptr<SceneSession> b) {
10698 return a->GetZOrder() > b->GetZOrder();
10699 });
10700 std::vector<sptr<SceneSession>> result;
10701 std::unordered_map<DisplayId, std::shared_ptr<SkRegion>> unaccountedSpaceMap;
10702 for (const auto& sceneSession : sceneSessionList) {
10703 if (sceneSession == nullptr) {
10704 TLOGE(WmsLogTag::WMS_MAIN, "invalid scene session");
10705 continue;
10706 }
10707 auto sessionProperty = sceneSession->GetSessionProperty();
10708 if (sessionProperty == nullptr) {
10709 TLOGE(WmsLogTag::WMS_MAIN, "get property of session: %{public}d", sceneSession->GetPersistentId());
10710 continue;
10711 }
10712 std::shared_ptr<SkRegion> unaccountedSpace = nullptr;
10713 auto displayId = sessionProperty->GetDisplayId();
10714 if (unaccountedSpaceMap.find(displayId) != unaccountedSpaceMap.end()) {
10715 unaccountedSpace = unaccountedSpaceMap[displayId];
10716 } else {
10717 unaccountedSpace = GetDisplayRegion(displayId);
10718 if (unaccountedSpace == nullptr) {
10719 TLOGE(WmsLogTag::WMS_MAIN, "get display region of display: %{public}" PRIu64, displayId);
10720 continue;
10721 }
10722 unaccountedSpaceMap[displayId] = unaccountedSpace;
10723 }
10724 WSRect wsRect = sceneSession->GetSessionRect();
10725 SkIRect windowBounds {.fLeft = wsRect.posX_, .fTop = wsRect.posY_,
10726 .fRight = wsRect.posX_ + wsRect.width_, .fBottom = wsRect.posY_ + wsRect.height_};
10727 SkRegion windowRegion(windowBounds);
10728 if (unaccountedSpace->quickReject(windowRegion)) {
10729 TLOGD(WmsLogTag::WMS_MAIN, "quick reject: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10730 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10731 continue;
10732 }
10733 if (!unaccountedSpace->intersects(windowRegion)) {
10734 TLOGD(WmsLogTag::WMS_MAIN, "no intersects: [l=%{public}d,t=%{public}d,r=%{public}d,b=%{public}d]",
10735 windowBounds.fLeft, windowBounds.fTop, windowBounds.fRight, windowBounds.fBottom);
10736 continue;
10737 }
10738 result.push_back(sceneSession);
10739 unaccountedSpace->op(windowRegion, SkRegion::Op::kDifference_Op);
10740 if (unaccountedSpace->isEmpty()) {
10741 break;
10742 }
10743 }
10744 sceneSessionList = result;
10745 }
10746
NotifyAllAccessibilityInfo()10747 void SceneSessionManager::NotifyAllAccessibilityInfo()
10748 {
10749 if (isUserBackground_) {
10750 TLOGD(WmsLogTag::WMS_MULTI_USER, "The user is in the background");
10751 return;
10752 }
10753 std::vector<sptr<SceneSession>> sceneSessionList;
10754 GetAllSceneSessionForAccessibility(sceneSessionList);
10755 FilterSceneSessionCovered(sceneSessionList);
10756
10757 std::vector<sptr<AccessibilityWindowInfo>> accessibilityInfo;
10758 FillAccessibilityInfo(sceneSessionList, accessibilityInfo);
10759
10760 for (const auto& item : accessibilityInfo) {
10761 TLOGD(WmsLogTag::WMS_MAIN, "notify accessibilityWindow wid = %{public}d, inWid = %{public}d, \
10762 bundle=%{public}s, bounds=(x = %{public}d, y = %{public}d, w = %{public}d, h = %{public}d)",
10763 item->wid_, item->innerWid_, item->bundleName_.c_str(),
10764 item->windowRect_.posX_, item->windowRect_.posY_, item->windowRect_.width_, item->windowRect_.height_);
10765 for (const auto& rect : item->touchHotAreas_) {
10766 TLOGD(WmsLogTag::WMS_MAIN, "window touch hot areas rect[x=%{public}d,y=%{public}d," \
10767 "w=%{public}d,h=%{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_);
10768 }
10769 }
10770
10771 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(accessibilityInfo,
10772 WindowUpdateType::WINDOW_UPDATE_ALL);
10773 }
10774
GetWindowStatus(WindowMode mode,SessionState sessionState,const sptr<WindowSessionProperty> & property)10775 WindowStatus SceneSessionManager::GetWindowStatus(WindowMode mode, SessionState sessionState,
10776 const sptr<WindowSessionProperty>& property)
10777 {
10778 auto windowStatus = WindowStatus::WINDOW_STATUS_UNDEFINED;
10779 if (property == nullptr) {
10780 return windowStatus;
10781 }
10782 if (mode == WindowMode::WINDOW_MODE_FLOATING) {
10783 windowStatus = WindowStatus::WINDOW_STATUS_FLOATING;
10784 if (property->GetMaximizeMode() == MaximizeMode::MODE_AVOID_SYSTEM_BAR) { // maximize floating
10785 windowStatus = WindowStatus::WINDOW_STATUS_MAXIMIZE;
10786 }
10787 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
10788 windowStatus = WindowStatus::WINDOW_STATUS_SPLITSCREEN;
10789 } else if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
10790 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10791 } else if (sessionState != SessionState::STATE_FOREGROUND && sessionState != SessionState::STATE_ACTIVE) {
10792 windowStatus = WindowStatus::WINDOW_STATUS_MINIMIZE;
10793 }
10794 return windowStatus;
10795 }
10796
GetCallingWindowWindowStatus(int32_t persistentId,WindowStatus & windowStatus)10797 WMError SceneSessionManager::GetCallingWindowWindowStatus(int32_t persistentId, WindowStatus& windowStatus)
10798 {
10799 if (!SessionPermission::IsStartedByInputMethod()) {
10800 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10801 return WMError::WM_ERROR_INVALID_PERMISSION;
10802 }
10803 auto scnSession = GetSceneSession(persistentId);
10804 if (scnSession == nullptr) {
10805 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10806 return WMError::WM_ERROR_NULLPTR;
10807 }
10808
10809 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10810 persistentId, scnSession->GetWindowType());
10811
10812 auto sessionProperty = scnSession->GetSessionProperty();
10813 if (sessionProperty == nullptr) {
10814 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10815 return WMError::WM_ERROR_INVALID_WINDOW;
10816 }
10817 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10818 auto callingSession = GetSceneSession(callingWindowId);
10819 if (callingSession == nullptr) {
10820 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10821 callingSession = GetSceneSession(focusedSessionId_);
10822 if (callingSession == nullptr) {
10823 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10824 return WMError::WM_ERROR_INVALID_WINDOW;
10825 }
10826 }
10827 if (callingSession->IsSystemSession()) {
10828 windowStatus = WindowStatus::WINDOW_STATUS_FULLSCREEN;
10829 } else {
10830 windowStatus = GetWindowStatus(callingSession->GetWindowMode(), callingSession->GetSessionState(),
10831 callingSession->GetSessionProperty());
10832 }
10833 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get WindowStatus persistentId: %{public}d windowstatus: %{public}d",
10834 persistentId, windowStatus);
10835 return WMError::WM_OK;
10836 }
10837
GetCallingWindowRect(int32_t persistentId,Rect & rect)10838 WMError SceneSessionManager::GetCallingWindowRect(int32_t persistentId, Rect& rect)
10839 {
10840 if (!SessionPermission::IsStartedByInputMethod()) {
10841 TLOGE(WmsLogTag::WMS_KEYBOARD, "permission is not allowed persistentId: %{public}d", persistentId);
10842 return WMError::WM_ERROR_INVALID_PERMISSION;
10843 }
10844 auto scnSession = GetSceneSession(persistentId);
10845 if (scnSession == nullptr) {
10846 TLOGE(WmsLogTag::WMS_KEYBOARD, "scnSession is null, persistentId: %{public}d", persistentId);
10847 return WMError::WM_ERROR_NULLPTR;
10848 }
10849 TLOGD(WmsLogTag::WMS_KEYBOARD, "persistentId: %{public}d, windowType: %{public}d",
10850 persistentId, scnSession->GetWindowType());
10851 auto sessionProperty = scnSession->GetSessionProperty();
10852 if (sessionProperty == nullptr) {
10853 TLOGE(WmsLogTag::WMS_KEYBOARD, "session property is null");
10854 return WMError::WM_ERROR_INVALID_WINDOW;
10855 }
10856 uint32_t callingWindowId = sessionProperty->GetCallingSessionId();
10857 auto callingSession = GetSceneSession(callingWindowId);
10858 if (callingSession == nullptr) {
10859 TLOGI(WmsLogTag::WMS_KEYBOARD, "callingsSession is null");
10860 callingSession = GetSceneSession(focusedSessionId_);
10861 if (callingSession == nullptr) {
10862 TLOGE(WmsLogTag::WMS_KEYBOARD, "callingsSession obtained through focusedSession fail");
10863 return WMError::WM_ERROR_INVALID_WINDOW;
10864 }
10865 }
10866 WSRect sessionRect = callingSession->GetSessionRect();
10867 rect = {sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_};
10868 TLOGI(WmsLogTag::WMS_KEYBOARD, "Get Rect persistentId: %{public}d, x: %{public}d, y: %{public}d, "
10869 "height: %{public}u, width: %{public}u", persistentId, rect.posX_, rect.posY_, rect.width_, rect.height_);
10870 return WMError::WM_OK;
10871 }
10872
GetWindowModeType(WindowModeType & windowModeType)10873 WMError SceneSessionManager::GetWindowModeType(WindowModeType& windowModeType)
10874 {
10875 if (!SessionPermission::IsSACalling()) {
10876 WLOGFE("GetWindowModeType permission denied!");
10877 return WMError::WM_ERROR_INVALID_PERMISSION;
10878 }
10879 windowModeType = CheckWindowModeType();
10880 return WMError::WM_OK;
10881 }
10882
GetWindowStyleType(WindowStyleType & windowStyleType)10883 WMError SceneSessionManager::GetWindowStyleType(WindowStyleType& windowStyleType)
10884 {
10885 if (!SessionPermission::IsSACalling()) {
10886 TLOGE(WmsLogTag::WMS_LIFE, "permission denied!");
10887 return WMError::WM_ERROR_INVALID_PERMISSION;
10888 }
10889 auto isPC = systemConfig_.uiType_ == UI_TYPE_PC;
10890 if (isPC) {
10891 windowStyleType = WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW;
10892 return WMError::WM_OK;
10893 }
10894 windowStyleType = systemConfig_.freeMultiWindowSupport_ && systemConfig_.freeMultiWindowEnable_ ?
10895 WindowStyleType::WINDOW_STYLE_FREE_MULTI_WINDOW : WindowStyleType::WINDOW_STYLE_DEFAULT;
10896 return WMError::WM_OK;
10897 }
10898
CheckSceneZOrder()10899 void SceneSessionManager::CheckSceneZOrder()
10900 {
10901 auto task = [this]() {
10902 AnomalyDetection::SceneZOrderCheckProcess();
10903 };
10904 taskScheduler_->PostAsyncTask(task, "CheckSceneZOrder");
10905 }
10906
NotifyEnterRecentTask(bool enterRecent)10907 WSError SceneSessionManager::NotifyEnterRecentTask(bool enterRecent)
10908 {
10909 TLOGI(WmsLogTag::WMS_IMMS, "enterRecent: %{public}u", enterRecent);
10910 enterRecent_.store(enterRecent);
10911 SetSystemAnimatedScenes(enterRecent ?
10912 SystemAnimatedSceneType::SCENE_ENTER_RECENTS : SystemAnimatedSceneType::SCENE_EXIT_RECENTS);
10913 auto task = [this] {
10914 for (auto persistentId : gestureBackEnableWindowIdSet_) {
10915 auto sceneSession = GetSceneSession(persistentId);
10916 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
10917 continue;
10918 }
10919 UpdateGestureBackEnabled(persistentId);
10920 }
10921 };
10922 taskScheduler_->PostAsyncTask(task, "UpdateGestureBackEnabledTask");
10923 return WSError::WS_OK;
10924 }
10925
GetMainWindowInfos(int32_t topNum,std::vector<MainWindowInfo> & topNInfo)10926 WMError SceneSessionManager::GetMainWindowInfos(int32_t topNum, std::vector<MainWindowInfo>& topNInfo)
10927 {
10928 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
10929 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
10930 return WMError::WM_ERROR_INVALID_PERMISSION;
10931 }
10932
10933 if (!topNInfo.empty() || (topNum <= 0)) {
10934 return WMError::WM_ERROR_INVALID_PARAM;
10935 }
10936
10937 TLOGD(WmsLogTag::WMS_MAIN, "topNum: %{public}d", topNum);
10938 auto func = [this, &topNum, &topNInfo](sptr<SceneSession> session) {
10939 if (session == nullptr) {
10940 return false;
10941 }
10942
10943 if (topNum == 0) {
10944 return true;
10945 }
10946
10947 if (!WindowHelper::IsMainWindow(session->GetWindowType()) || !IsSessionVisibleForeground(session)) {
10948 TLOGD(WmsLogTag::WMS_MAIN, "not main window %{public}d", session->GetWindowType());
10949 return false;
10950 }
10951
10952 MainWindowInfo info;
10953 info.pid_ = session->GetCallingPid();
10954 info.bundleName_ = session->GetSessionInfo().bundleName_;
10955 topNInfo.push_back(info);
10956 topNum--;
10957 TLOGE(WmsLogTag::WMS_MAIN, "topnNum: %{public}d, pid: %{public}d, bundleName: %{public}s",
10958 topNum, info.pid_, info.bundleName_.c_str());
10959 return false;
10960 };
10961 TraverseSessionTree(func, true);
10962
10963 return WMError::WM_OK;
10964 }
10965
GetWindowIdsByCoordinate(DisplayId displayId,int32_t windowNumber,int32_t x,int32_t y,std::vector<int32_t> & windowIds)10966 WMError SceneSessionManager::GetWindowIdsByCoordinate(DisplayId displayId, int32_t windowNumber,
10967 int32_t x, int32_t y, std::vector<int32_t>& windowIds)
10968 {
10969 TLOGD(WmsLogTag::DEFAULT, "displayId %{public}" PRIu64 " windowNumber %{public}d x %{public}d y %{public}d",
10970 displayId, windowNumber, x, y);
10971 if (displayId == DISPLAY_ID_INVALID) {
10972 TLOGE(WmsLogTag::DEFAULT, "displayId is invalid");
10973 return WMError::WM_ERROR_INVALID_PARAM;
10974 }
10975 bool findAllWindow = windowNumber <= 0;
10976 bool checkPoint = (x >= 0 && y >= 0);
10977 std::string callerBundleName = SessionPermission::GetCallingBundleName();
10978 auto func = [displayId, callerBundleName = std::move(callerBundleName), checkPoint, x, y,
10979 findAllWindow, &windowNumber, &windowIds](const sptr<SceneSession>& session) {
10980 if (session == nullptr) {
10981 return false;
10982 }
10983 auto sessionProperty = session->GetSessionProperty();
10984 if (sessionProperty == nullptr) {
10985 return false;
10986 }
10987 if (!findAllWindow && windowNumber == 0) {
10988 return true;
10989 }
10990 bool isSameBundleName = session->GetSessionInfo().bundleName_ == callerBundleName;
10991 bool isSameDisplayId = sessionProperty->GetDisplayId() == displayId;
10992 bool isRsVisible = session->GetRSVisible();
10993 WSRect windowRect = session->GetSessionRect();
10994 bool isPointInWindowRect = SessionHelper::IsPointInRect(x, y, SessionHelper::TransferToRect(windowRect));
10995 TLOGND(WmsLogTag::DEFAULT, "persistentId %{public}d bundleName %{public}s displayId %{public}" PRIu64
10996 " isRsVisible %{public}d checkPoint %{public}d isPointInWindowRect %{public}d",
10997 session->GetPersistentId(), session->GetSessionInfo().bundleName_.c_str(),
10998 sessionProperty->GetDisplayId(), isRsVisible, checkPoint, isPointInWindowRect);
10999 if (!isSameBundleName || !isSameDisplayId || !isRsVisible || (checkPoint && !isPointInWindowRect)) {
11000 return false;
11001 }
11002 windowIds.emplace_back(session->GetPersistentId());
11003 windowNumber--;
11004 return false;
11005 };
11006 auto task = [this, func = std::move(func)] {
11007 TraverseSessionTree(func, true);
11008 return WMError::WM_OK;
11009 };
11010 return taskScheduler_->PostSyncTask(task, __func__);
11011 }
11012
GetAllMainWindowInfos(std::vector<MainWindowInfo> & infos) const11013 WMError SceneSessionManager::GetAllMainWindowInfos(std::vector<MainWindowInfo>& infos) const
11014 {
11015 if (!infos.empty()) {
11016 TLOGE(WmsLogTag::WMS_MAIN, "Input param invalid, infos must be empty.");
11017 return WMError::WM_ERROR_INVALID_PARAM;
11018 }
11019 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11020 TLOGE(WmsLogTag::WMS_MAIN, "Get all mainWindow infos failed, only support SA calling.");
11021 return WMError::WM_ERROR_INVALID_PERMISSION;
11022 }
11023 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11024 for (const auto& iter : sceneSessionMap_) {
11025 auto& session = iter.second;
11026 if (session == nullptr || !WindowHelper::IsMainWindow(session->GetWindowType())) {
11027 continue;
11028 }
11029 MainWindowInfo info;
11030 auto abilityInfo = session->GetSessionInfo().abilityInfo;
11031 info.pid_ = session->GetCallingPid();
11032 info.bundleName_ = session->GetSessionInfo().bundleName_;
11033 info.persistentId_ = session->GetPersistentId();
11034 if (IsAtomicServiceFreeInstall(session->GetSessionInfo())) {
11035 TLOGI(WmsLogTag::WMS_MAIN, "id:%{public}d is atomicServiceInstall", session->GetPersistentId());
11036 info.bundleType_ = static_cast<int32_t>(AppExecFwk::BundleType::ATOMIC_SERVICE);
11037 infos.push_back(info);
11038 } else if (abilityInfo != nullptr) {
11039 info.bundleType_ = static_cast<int32_t>(abilityInfo->applicationInfo.bundleType);
11040 infos.push_back(info);
11041 TLOGD(WmsLogTag::WMS_MAIN, "Get mainWindow info: Session id:%{public}d, "
11042 "bundleName:%{public}s, bundleType:%{public}d", session->GetPersistentId(),
11043 info.bundleName_.c_str(), info.bundleType_);
11044 }
11045 }
11046 return WMError::WM_OK;
11047 }
11048
ClearMainSessions(const std::vector<int32_t> & persistentIds,std::vector<int32_t> & clearFailedIds)11049 WMError SceneSessionManager::ClearMainSessions(const std::vector<int32_t>& persistentIds,
11050 std::vector<int32_t>& clearFailedIds)
11051 {
11052 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11053 TLOGE(WmsLogTag::WMS_MAIN, "Clear main sessions failed, only support SA calling.");
11054 return WMError::WM_ERROR_INVALID_PERMISSION;
11055 }
11056 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
11057 TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted");
11058 return WMError::WM_ERROR_INVALID_PERMISSION;
11059 }
11060 clearFailedIds.clear();
11061 for (const auto persistentId : persistentIds) {
11062 auto sceneSession = GetSceneSession(persistentId);
11063 if (sceneSession == nullptr) {
11064 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not found.", persistentId);
11065 clearFailedIds.push_back(persistentId);
11066 continue;
11067 }
11068 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11069 TLOGW(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11070 clearFailedIds.push_back(persistentId);
11071 continue;
11072 }
11073 sceneSession->Clear();
11074 TLOGD(WmsLogTag::WMS_MAIN, "Clear succeed: session id:%{public}d.", persistentId);
11075 }
11076 return WMError::WM_OK;
11077 }
11078
UpdateDisplayHookInfo(int32_t uid,uint32_t width,uint32_t height,float_t density,bool enable)11079 WMError SceneSessionManager::UpdateDisplayHookInfo(int32_t uid, uint32_t width, uint32_t height, float_t density,
11080 bool enable)
11081 {
11082 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, enable: %{public}d",
11083 width, height, density, enable);
11084
11085 DMHookInfo dmHookInfo;
11086 dmHookInfo.width_ = width;
11087 dmHookInfo.height_ = height;
11088 dmHookInfo.density_ = density;
11089 dmHookInfo.rotation_ = 0;
11090 dmHookInfo.enableHookRotation_ = false;
11091 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11092 return WMError::WM_OK;
11093 }
11094
UpdateAppHookDisplayInfo(int32_t uid,const HookInfo & hookInfo,bool enable)11095 WMError SceneSessionManager::UpdateAppHookDisplayInfo(int32_t uid, const HookInfo& hookInfo, bool enable)
11096 {
11097 TLOGI(WmsLogTag::WMS_LAYOUT, "width: %{public}u, height: %{public}u, density: %{public}f, rotation: %{public}u, "
11098 "enableHookRotation: %{public}d, enable: %{public}d", hookInfo.width_, hookInfo.height_, hookInfo.density_,
11099 hookInfo.rotation_, hookInfo.enableHookRotation_, enable);
11100
11101 DMHookInfo dmHookInfo;
11102 dmHookInfo.width_ = hookInfo.width_;
11103 dmHookInfo.height_ = hookInfo.height_;
11104 dmHookInfo.density_ = hookInfo.density_;
11105 dmHookInfo.rotation_ = hookInfo.rotation_;
11106 dmHookInfo.enableHookRotation_ = hookInfo.enableHookRotation_;
11107 ScreenSessionManagerClient::GetInstance().UpdateDisplayHookInfo(uid, enable, dmHookInfo);
11108 return WMError::WM_OK;
11109 }
11110
OnScreenFoldStatusChanged(const std::vector<std::string> & screenFoldInfo)11111 void DisplayChangeListener::OnScreenFoldStatusChanged(const std::vector<std::string>& screenFoldInfo)
11112 {
11113 SceneSessionManager::GetInstance().ReportScreenFoldStatusChange(screenFoldInfo);
11114 }
11115
ReportScreenFoldStatusChange(const std::vector<std::string> & screenFoldInfo)11116 WMError SceneSessionManager::ReportScreenFoldStatusChange(const std::vector<std::string>& screenFoldInfo)
11117 {
11118 ScreenFoldData screenFoldData;
11119 WMError ret = MakeScreenFoldData(screenFoldInfo, screenFoldData);
11120 if (ret != WMError::WM_OK) {
11121 return ret;
11122 }
11123 return CheckAndReportScreenFoldStatus(screenFoldData);
11124 }
11125
MakeScreenFoldData(const std::vector<std::string> & screenFoldInfo,ScreenFoldData & screenFoldData)11126 WMError SceneSessionManager::MakeScreenFoldData(const std::vector<std::string>& screenFoldInfo,
11127 ScreenFoldData& screenFoldData)
11128 {
11129 if (screenFoldInfo.size() < ScreenFoldData::DMS_PARAM_NUMBER) {
11130 TLOGI(WmsLogTag::DMS, "Error: Init DMS param number is wrong.");
11131 return WMError::WM_DO_NOTHING;
11132 }
11133
11134 screenFoldData.currentScreenFoldStatus_ = std::stoi(screenFoldInfo[0]); // 0: current screen fold status
11135 screenFoldData.nextScreenFoldStatus_ = std::stoi(screenFoldInfo[1]); // 1: next screen fold status
11136 screenFoldData.currentScreenFoldStatusDuration_ = std::stoi(screenFoldInfo[2]); // 2: current duration
11137 screenFoldData.postureAngle_ = std::atof(screenFoldInfo[3].c_str()); // 3: posture angle (type: float)
11138 screenFoldData.screenRotation_ = std::stoi(screenFoldInfo[4]); // 4: screen rotation
11139 if (!screenFoldData.GetTypeCThermalWithUtil()) {
11140 TLOGI(WmsLogTag::DMS, "Error: fail to get typeC thermal.");
11141 return WMError::WM_DO_NOTHING;
11142 }
11143 AppExecFwk::ElementName element = {};
11144 WSError ret = GetFocusSessionElement(element);
11145 if (ret != WSError::WS_OK) {
11146 TLOGI(WmsLogTag::DMS, "Error: fail to get focused package name.");
11147 return WMError::WM_DO_NOTHING;
11148 }
11149 screenFoldData.SetFocusedPkgName(element.GetURI());
11150 return WMError::WM_OK;
11151 }
11152
CheckAndReportScreenFoldStatus(ScreenFoldData & data)11153 WMError SceneSessionManager::CheckAndReportScreenFoldStatus(ScreenFoldData& data)
11154 {
11155 static ScreenFoldData lastScreenHalfFoldData;
11156 if (data.nextScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11157 lastScreenHalfFoldData = data;
11158 return WMError::WM_DO_NOTHING;
11159 }
11160 WMError lastScreenHalfFoldReportRet = WMError::WM_OK;
11161 if (data.currentScreenFoldStatus_ == static_cast<int32_t>(FoldStatus::HALF_FOLD)) {
11162 if (data.currentScreenFoldStatusDuration_ >= ScreenFoldData::HALF_FOLD_REPORT_TRIGGER_DURATION) {
11163 lastScreenHalfFoldReportRet = ReportScreenFoldStatus(lastScreenHalfFoldData);
11164 } else if (lastScreenHalfFoldData.currentScreenFoldStatus_ != ScreenFoldData::INVALID_VALUE) {
11165 // if stay at half-fold less than 15s, combine this change with last
11166 data.currentScreenFoldStatus_ = lastScreenHalfFoldData.currentScreenFoldStatus_;
11167 data.currentScreenFoldStatusDuration_ += lastScreenHalfFoldData.currentScreenFoldStatusDuration_;
11168 data.postureAngle_ = lastScreenHalfFoldData.postureAngle_;
11169 }
11170 lastScreenHalfFoldData.SetInvalid();
11171 }
11172 WMError currentScreenFoldStatusReportRet = ReportScreenFoldStatus(data);
11173 return (currentScreenFoldStatusReportRet == WMError::WM_OK) ? lastScreenHalfFoldReportRet :
11174 currentScreenFoldStatusReportRet;
11175 }
11176
11177 // report screen_fold_status event when it changes to fold/expand or stays 15s at half-fold
ReportScreenFoldStatus(const ScreenFoldData & data)11178 WMError SceneSessionManager::ReportScreenFoldStatus(const ScreenFoldData& data)
11179 {
11180 if (data.currentScreenFoldStatus_ == ScreenFoldData::INVALID_VALUE) {
11181 return WMError::WM_DO_NOTHING;
11182 }
11183
11184 int32_t ret = HiSysEventWrite(
11185 OHOS::HiviewDFX::HiSysEvent::Domain::FOLDSTATE_UE,
11186 "FOLDSCREEN_STATE_CHANGE",
11187 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
11188 "PNAMEID", "OCCUPATION", "PVERSIONID", "OCCUPATION",
11189 "LASTFOLDSTATE", data.currentScreenFoldStatus_,
11190 "CURRENTFOLDSTATE", data.nextScreenFoldStatus_,
11191 "STATE", -1,
11192 "TIME", data.currentScreenFoldStatusDuration_,
11193 "ROTATION", data.screenRotation_,
11194 "PACKAGE", data.focusedPackageName_,
11195 "ANGLE", data.postureAngle_,
11196 "TYPECTHERMAL", data.typeCThermal_,
11197 "SCREENTHERMAL", -1,
11198 "SCANGLE", -1,
11199 "ISTENT", -1);
11200 if (ret != 0) {
11201 TLOGE(WmsLogTag::DMS, "Write HiSysEvent error, ret: %{public}d.", ret);
11202 return WMError::WM_DO_NOTHING;
11203 }
11204 return WMError::WM_OK;
11205 }
11206
UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData,uint64_t userid)11207 void SceneSessionManager::UpdateSecSurfaceInfo(std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid)
11208 {
11209 if (currentUserId_ != static_cast<int32_t>(userid)) {
11210 TLOGW(WmsLogTag::WMS_MULTI_USER, "currentUserId_:%{public}d userid:%{public}" PRIu64,
11211 currentUserId_.load(), userid);
11212 return;
11213 }
11214 auto secSurfaceInfoMap = secExtensionData->GetSecData();
11215 auto task = [secSurfaceInfoMap]()-> WSError {
11216 SceneInputManager::GetInstance().UpdateSecSurfaceInfo(secSurfaceInfoMap);
11217 return WSError::WS_OK;
11218 };
11219 taskScheduler_->PostAsyncTask(task, "UpdateSecSurfaceInfo");
11220 }
11221
RegisterSecSurfaceInfoListener()11222 void SceneSessionManager::RegisterSecSurfaceInfoListener()
11223 {
11224 auto callBack = [this](std::shared_ptr<RSUIExtensionData> secExtensionData, uint64_t userid) {
11225 this->UpdateSecSurfaceInfo(secExtensionData, userid);
11226 };
11227 TLOGI(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener");
11228 if (rsInterface_.RegisterUIExtensionCallback(currentUserId_, callBack) != WM_OK) {
11229 TLOGE(WmsLogTag::WMS_EVENT, "RegisterSecSurfaceInfoListener failed");
11230 }
11231 }
11232
SetAppForceLandscapeConfig(const std::string & bundleName,const AppForceLandscapeConfig & config)11233 WSError SceneSessionManager::SetAppForceLandscapeConfig(const std::string& bundleName,
11234 const AppForceLandscapeConfig& config)
11235 {
11236 if (bundleName.empty()) {
11237 TLOGE(WmsLogTag::DEFAULT, "bundle name is empty");
11238 return WSError::WS_ERROR_NULLPTR;
11239 }
11240 std::unique_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11241 appForceLandscapeMap_[bundleName] = config;
11242 TLOGI(WmsLogTag::DEFAULT, "app: %{public}s, mode: %{public}d, homePage: %{public}s",
11243 bundleName.c_str(), config.mode_, config.homePage_.c_str());
11244 return WSError::WS_OK;
11245 }
11246
GetAppForceLandscapeConfig(const std::string & bundleName)11247 AppForceLandscapeConfig SceneSessionManager::GetAppForceLandscapeConfig(const std::string& bundleName)
11248 {
11249 if (bundleName.empty()) {
11250 return {};
11251 }
11252 std::shared_lock<std::shared_mutex> lock(appForceLandscapeMutex_);
11253 if (appForceLandscapeMap_.empty() ||
11254 appForceLandscapeMap_.find(bundleName) == appForceLandscapeMap_.end()) {
11255 TLOGD(WmsLogTag::DEFAULT, "app: %{public}s, config not find", bundleName.c_str());
11256 return {};
11257 }
11258 return appForceLandscapeMap_[bundleName];
11259 }
11260
TerminateSessionByPersistentId(int32_t persistentId)11261 WMError SceneSessionManager::TerminateSessionByPersistentId(int32_t persistentId)
11262 {
11263 if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_KILL_APP_PROCESS)) {
11264 TLOGE(WmsLogTag::WMS_LIFE, "The caller has no permission granted.");
11265 return WMError::WM_ERROR_INVALID_PERMISSION;
11266 }
11267 if (!SessionPermission::IsSystemAppCall()) {
11268 TLOGE(WmsLogTag::WMS_LIFE, "The caller is not system app.");
11269 return WMError::WM_ERROR_NOT_SYSTEM_APP;
11270 }
11271 auto sceneSession = GetSceneSession(persistentId);
11272 if (sceneSession == nullptr) {
11273 TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", persistentId);
11274 return WMError::WM_ERROR_INVALID_PARAM;
11275 }
11276 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
11277 TLOGE(WmsLogTag::WMS_MAIN, "Session id:%{public}d is not mainWindow.", persistentId);
11278 return WMError::WM_ERROR_INVALID_PARAM;
11279 }
11280 sceneSession->Clear(true);
11281 TLOGI(WmsLogTag::WMS_LIFE, "Terminate success, id:%{public}d.", persistentId);
11282 return WMError::WM_OK;
11283 }
11284
SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc & processBackEventFunc)11285 void SceneSessionManager::SetRootSceneProcessBackEventFunc(const RootSceneProcessBackEventFunc& processBackEventFunc)
11286 {
11287 rootSceneProcessBackEventFunc_ = processBackEventFunc;
11288 TLOGI(WmsLogTag::WMS_EVENT, "called");
11289 }
11290
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<int32_t> & persistentIds,std::vector<uint64_t> & surfaceNodeIds)11291 WMError SceneSessionManager::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
11292 const std::vector<int32_t>& persistentIds, std::vector<uint64_t>& surfaceNodeIds)
11293 {
11294 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11295 TLOGE(WmsLogTag::DEFAULT, "The caller has no permission granted.");
11296 return WMError::WM_ERROR_INVALID_PERMISSION;
11297 }
11298
11299 surfaceNodeIds.clear();
11300 TLOGI(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId, pid:%{public}d", pid);
11301 for (auto persistentId : persistentIds) {
11302 TLOGI(WmsLogTag::DEFAULT, "convert wid:%{public}d", persistentId);
11303 auto sceneSession = GetSceneSession(persistentId);
11304 if (sceneSession == nullptr) {
11305 continue;
11306 }
11307 auto callingPid = sceneSession->GetCallingPid();
11308 auto surfaceNode = sceneSession->GetSurfaceNode();
11309 if (surfaceNode != nullptr && callingPid == pid) {
11310 surfaceNodeIds.push_back(surfaceNode->GetId());
11311 auto leashWinSurfaceNode = sceneSession->GetLeashWinSurfaceNode();
11312 if (leashWinSurfaceNode != nullptr) {
11313 surfaceNodeIds.push_back(leashWinSurfaceNode->GetId());
11314 surfaceNodeIds.push_back(persistentId);
11315 }
11316 }
11317 }
11318
11319 return WMError::WM_OK;
11320 }
11321
ReleaseForegroundSessionScreenLock()11322 WMError SceneSessionManager::ReleaseForegroundSessionScreenLock()
11323 {
11324 if (!SessionPermission::IsSACalling() && !SessionPermission::IsShellCall()) {
11325 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11326 return WMError::WM_ERROR_INVALID_PERMISSION;
11327 }
11328 #ifdef POWER_MANAGER_ENABLE
11329 auto task = [this] {
11330 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11331 for (const auto& [persistentId, sceneSession] : sceneSessionMap_) {
11332 if (!IsSessionVisibleForeground(sceneSession) || sceneSession->keepScreenLock_ == nullptr) {
11333 continue;
11334 }
11335 auto res = sceneSession->keepScreenLock_->UnLock();
11336 if (res != ERR_OK) {
11337 TLOGNE(WmsLogTag::DEFAULT,
11338 "release screen lock failed: window: [%{public}d, %{public}s], err: %{public}d",
11339 persistentId, sceneSession->GetWindowName().c_str(), res);
11340 return WMError::WM_ERROR_INVALID_OPERATION;
11341 }
11342 TLOGNI(WmsLogTag::DEFAULT, "release screen lock success: window: [%{public}d, %{public}s]",
11343 persistentId, sceneSession->GetWindowName().c_str());
11344 }
11345 return WMError::WM_OK;
11346 };
11347 return taskScheduler_->PostSyncTask(task, __func__);
11348 #else
11349 TLOGD(WmsLogTag::DEFAULT, "Can not find the sub system of PowerMgr");
11350 return WMError::WM_OK;
11351 #endif
11352 }
11353
SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc & func)11354 void SceneSessionManager::SetCloseTargetFloatWindowFunc(const ProcessCloseTargetFloatWindowFunc& func)
11355 {
11356 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "in");
11357 auto task = [this, func] {
11358 closeTargetFloatWindowFunc_ = func;
11359 };
11360 taskScheduler_->PostTask(task, __func__);
11361 }
11362
CloseTargetFloatWindow(const std::string & bundleName)11363 WMError SceneSessionManager::CloseTargetFloatWindow(const std::string& bundleName)
11364 {
11365 if (!SessionPermission::IsSystemServiceCalling(false)) {
11366 TLOGE(WmsLogTag::WMS_MULTI_WINDOW, "failed, not system service called.");
11367 return WMError::WM_ERROR_INVALID_PERMISSION;
11368 }
11369 auto task = [this, bundleName] {
11370 if (closeTargetFloatWindowFunc_) {
11371 TLOGNI(WmsLogTag::WMS_MULTI_WINDOW, "bundleName:%{public}s", bundleName.c_str());
11372 closeTargetFloatWindowFunc_(bundleName);
11373 }
11374 };
11375 taskScheduler_->PostTask(task, __func__);
11376 return WMError::WM_OK;
11377 }
11378
UpdatePiPWindowStateChanged(const std::string & bundleName,bool isForeground)11379 void SceneSessionManager::UpdatePiPWindowStateChanged(const std::string& bundleName, bool isForeground)
11380 {
11381 SessionManagerAgentController::GetInstance().UpdatePiPWindowStateChanged(bundleName, isForeground);
11382 }
11383
CloseTargetPiPWindow(const std::string & bundleName)11384 WMError SceneSessionManager::CloseTargetPiPWindow(const std::string& bundleName)
11385 {
11386 if (!SessionPermission::IsSystemServiceCalling(false)) {
11387 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11388 return WMError::WM_ERROR_INVALID_PERMISSION;
11389 }
11390 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11391 for (const auto& iter : sceneSessionMap_) {
11392 auto& session = iter.second;
11393 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP &&
11394 session->GetSessionInfo().bundleName_ == bundleName) {
11395 session->NotifyCloseExistPipWindow();
11396 break;
11397 }
11398 }
11399 return WMError::WM_OK;
11400 }
11401
GetCurrentPiPWindowInfo(std::string & bundleName)11402 WMError SceneSessionManager::GetCurrentPiPWindowInfo(std::string& bundleName)
11403 {
11404 if (!SessionPermission::IsSystemServiceCalling(false)) {
11405 TLOGE(WmsLogTag::WMS_PIP, "failed, not system service called.");
11406 return WMError::WM_ERROR_INVALID_PERMISSION;
11407 }
11408 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
11409 for (const auto& iter : sceneSessionMap_) {
11410 auto& session = iter.second;
11411 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
11412 bundleName = session->GetSessionInfo().bundleName_;
11413 return WMError::WM_OK;
11414 }
11415 }
11416 TLOGW(WmsLogTag::WMS_PIP, "no PiP window");
11417 return WMError::WM_OK;
11418 }
11419
UpdateDarkColorModeToRS()11420 void SceneSessionManager::UpdateDarkColorModeToRS()
11421 {
11422 std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::Context::GetApplicationContext();
11423 if (appContext == nullptr) {
11424 TLOGE(WmsLogTag::DEFAULT, "app context is nullptr");
11425 return;
11426 }
11427 std::shared_ptr<AppExecFwk::Configuration> config = appContext->GetConfiguration();
11428 if (config == nullptr) {
11429 TLOGE(WmsLogTag::DEFAULT, "app configuration is nullptr");
11430 return;
11431 }
11432 std::string colorMode = config->GetItem(AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
11433 bool isDark = (colorMode == AppExecFwk::ConfigurationInner::COLOR_MODE_DARK);
11434 bool ret = RSInterfaces::GetInstance().SetGlobalDarkColorMode(isDark);
11435 TLOGI(WmsLogTag::DEFAULT, "colorMode: %{public}s, ret: %{public}d",
11436 colorMode.c_str(), ret);
11437 }
11438
IsPcWindow(bool & isPcWindow)11439 WMError SceneSessionManager::IsPcWindow(bool& isPcWindow)
11440 {
11441 isPcWindow = (systemConfig_.uiType_ == UI_TYPE_PC);
11442 return WMError::WM_OK;
11443 }
11444
IsPcOrPadFreeMultiWindowMode(bool & isPcOrPadFreeMultiWindowMode)11445 WMError SceneSessionManager::IsPcOrPadFreeMultiWindowMode(bool& isPcOrPadFreeMultiWindowMode)
11446 {
11447 isPcOrPadFreeMultiWindowMode = (systemConfig_.uiType_ == UI_TYPE_PC || systemConfig_.freeMultiWindowEnable_);
11448 return WMError::WM_OK;
11449 }
11450
GetDisplayIdByWindowId(const std::vector<uint64_t> & windowIds,std::unordered_map<uint64_t,DisplayId> & windowDisplayIdMap)11451 WMError SceneSessionManager::GetDisplayIdByWindowId(const std::vector<uint64_t>& windowIds,
11452 std::unordered_map<uint64_t, DisplayId>& windowDisplayIdMap)
11453 {
11454 if (!SessionPermission::IsSystemCalling()) {
11455 TLOGE(WmsLogTag::DEFAULT, "permission denied!");
11456 return WMError::WM_ERROR_INVALID_PERMISSION;
11457 }
11458
11459 auto task = [this, windowIds, &windowDisplayIdMap] {
11460 for (const uint64_t windowId : windowIds) {
11461 sptr<SceneSession> session = GetSceneSession(static_cast<int32_t>(windowId));
11462 if (session == nullptr) {
11463 continue;
11464 }
11465 sptr<WindowSessionProperty> sessionProperty = session->GetSessionProperty();
11466 if (sessionProperty == nullptr) {
11467 continue;
11468 }
11469 DisplayId displayId = sessionProperty->GetDisplayId();
11470 TLOGNI(WmsLogTag::DEFAULT, "windowId:%{public}" PRIu64 ", displayId:%{public}" PRIu64,
11471 windowId, displayId);
11472 windowDisplayIdMap.insert({windowId, displayId});
11473 }
11474 return WMError::WM_OK;
11475 };
11476 return taskScheduler_->PostSyncTask(task, __func__);
11477 }
11478
IsLastFrameLayoutFinished(bool & isLayoutFinished)11479 WSError SceneSessionManager::IsLastFrameLayoutFinished(bool& isLayoutFinished)
11480 {
11481 if (isRootSceneLastFrameLayoutFinishedFunc_ == nullptr) {
11482 TLOGE(WmsLogTag::WMS_IMMS, "isRootSceneLastFrameLayoutFinishedFunc is null");
11483 return WSError::WS_ERROR_NULLPTR;
11484 }
11485 isLayoutFinished = isRootSceneLastFrameLayoutFinishedFunc_();
11486 return WSError::WS_OK;
11487 }
11488
IsWindowRectAutoSave(const std::string & key,bool & enabled)11489 WMError SceneSessionManager::IsWindowRectAutoSave(const std::string& key, bool& enabled)
11490 {
11491 std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11492 if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11493 enabled = iter->second;
11494 } else {
11495 enabled = false;
11496 }
11497 return WMError::WM_OK;
11498 }
11499
SetIsWindowRectAutoSave(const std::string & key,bool enabled)11500 void SceneSessionManager::SetIsWindowRectAutoSave(const std::string& key, bool enabled)
11501 {
11502 std::unique_lock<std::mutex> lock(isWindowRectAutoSaveMapMutex_);
11503 if (auto iter = isWindowRectAutoSaveMap_.find(key); iter != isWindowRectAutoSaveMap_.end()) {
11504 if (!enabled) {
11505 isWindowRectAutoSaveMap_.erase(key);
11506 } else {
11507 iter->second = enabled;
11508 }
11509 } else {
11510 if (enabled) {
11511 isWindowRectAutoSaveMap_.insert({key, enabled});
11512 }
11513 }
11514 }
11515
RemoveAppInfo(const std::string & bundleName)11516 void SceneSessionManager::RemoveAppInfo(const std::string& bundleName)
11517 {
11518 AbilityInfoManager::GetInstance().RemoveAppInfo(bundleName);
11519 }
11520
GetRootMainWindowId(int32_t persistentId,int32_t & hostWindowId)11521 WMError SceneSessionManager::GetRootMainWindowId(int32_t persistentId, int32_t& hostWindowId)
11522 {
11523 if (!SessionPermission::IsSystemServiceCalling()) {
11524 TLOGE(WmsLogTag::WMS_MAIN, "permission denied!");
11525 return WMError::WM_ERROR_INVALID_PERMISSION;
11526 }
11527 const char* const where = __func__;
11528 auto task = [this, persistentId, &hostWindowId, where]() {
11529 hostWindowId = INVALID_WINDOW_ID;
11530 sptr<Session> session = GetSceneSession(persistentId);
11531 while (session && SessionHelper::IsSubWindow(session->GetWindowType()))
11532 {
11533 session = session->GetParentSession();
11534 }
11535 if (session && SessionHelper::IsMainWindow(session->GetWindowType())) {
11536 hostWindowId = session->GetPersistentId();
11537 }
11538 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s: persistentId:%{public}d hostWindowId:%{public}d",
11539 where, persistentId, hostWindowId);
11540 return WMError::WM_OK;
11541 };
11542 return taskScheduler_->PostSyncTask(task, where);
11543 }
11544 } // namespace OHOS::Rosen